如何通过连接和基于行的限制(分页)在休眠中获得不同的结果?
我正在尝试在连接到其他条件的 Hibernate Criteria 查询上使用基于行的限制(例如:setFirstResult(5)
和 setMaxResults(10)
)来实现分页表。
可以理解的是,数据被随机切断; 其原因在此处进行了解释。
作为解决方案,该页面建议使用“第二个 sql select”而不是联接。
如何将现有条件查询(使用 createAlias()
进行连接)转换为使用嵌套选择?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
您可以通过请求不同 id 的列表而不是不同水合对象的列表来实现所需的结果。
只需将其添加到您的条件中即可:
现在您将根据基于行的限制获得正确数量的结果。 这样做的原因是,投影将执行唯一性检查作为 sql 查询的一部分,而不是 ResultTransformer 执行的操作,即在之后过滤结果的唯一性已执行sql查询。
值得注意的是,您现在将获得一个 id 列表,而不是获取对象列表,稍后您可以使用它来从休眠中水合对象。
You can achieve the desired result by requesting a list of distinct ids instead of a list of distinct hydrated objects.
Simply add this to your criteria:
Now you'll get the correct number of results according to your row-based limiting. The reason this works is because the projection will perform the distinctness check as part of the sql query, instead of what a ResultTransformer does which is to filter the results for distinctness after the sql query has been performed.
Worth noting is that instead of getting a list of objects, you will now get a list of ids, which you can use to hydrate objects from hibernate later.
我正在将这个与我的代码一起使用。
只需将其添加到您的标准中即可:
该代码将类似于本机 sql 的 select different * from table 。
I am using this one with my code.
Simply add this to your criteria:
that code will be like the select distinct * from table of the native sql.
在 FishBoy 的建议的基础上略有改进。
可以在一次命中中执行这种查询,而不是在两个单独的阶段中执行。 即下面的单个查询将正确分页不同的结果,并且还返回实体而不仅仅是 ID。
只需使用具有 id 投影的 DetachedCriteria 作为子查询,然后在主 Criteria 对象上添加分页值即可。
它看起来像这样:
A slight improvement building on FishBoy's suggestion.
It is possible to do this kind of query in one hit, rather than in two separate stages. i.e. the single query below will page distinct results correctly, and also return entities instead of just IDs.
Simply use a DetachedCriteria with an id projection as a subquery, and then add paging values on the main Criteria object.
It will look something like this:
对 @FishBoy 建议的一个小改进是使用 id 投影,这样您就不必对标识符属性名称进行硬编码。
A small improvement to @FishBoy's suggestion is to use the id projection, so you don't have to hard-code the identifier property name.
解决方案:
效果很好。
The solution:
works very well.
这对我有帮助:D
This helped me :D
如果你想使用 ORDER BY,只需添加:
if you want to use ORDER BY, just add:
我现在将解释一个不同的解决方案,您可以使用正常的查询和分页方法,而不会出现可能重复或抑制项目的问题。
该解决方案的优点是:
完整的文章可以在 我的博客
Hibernate 不仅可以在设计时而且可以在运行时通过查询执行来定义关联获取方法。 因此,我们将这种方法与简单的反射材料结合使用,并且还可以自动更改仅针对集合属性的查询属性获取算法的过程。
首先,我们创建一个方法来解析实体类中的所有集合属性:
完成此操作后,您可以使用这个小帮助器方法,建议您的条件对象在该查询上将 FetchMode 更改为 SELECT。
这样做与在设计时定义实体的 FetchMode 不同。 因此,您可以在 UI 中对分页算法使用正常的连接关联获取,因为这在大多数情况下不是关键部分,更重要的是尽快获得结果。
I will now explain a different solution, where you can use the normal query and pagination method without having the problem of possibly duplicates or suppressed items.
This Solution has the advance that it is:
The complete Article can be found on my blog
Hibernate gives the possibility to define the association fetching method not only at design time but also at runtime by a query execution. So we use this aproach in conjunction with a simple relfection stuff and can also automate the process of changing the query property fetching algorithm only for collection properties.
First we create a method which resolves all collection properties from the Entity Class:
After doing that you can use this little helper method do advise your criteria object to change the FetchMode to SELECT on that query.
Doing that is different from define the FetchMode of your entities at design time. So you can use the normal join association fetching on paging algorithms in you UI, because this is most of the time not the critical part and it is more important to have your results as quick as possible.
下面是我们可以通过多重投影来执行 Distinct
ExtraProjections.java
示例用法:
引用自 https ://forum.hibernate.org/viewtopic.php?t=964506
Below is the way we can do Multiple projection to perform Distinct
ExtraProjections.java
Sample Usage:
Referenced from https://forum.hibernate.org/viewtopic.php?t=964506
在某些情况下
NullPointerException
!没有
criteria.setProjection(Projections.distinct(Projections.property("id")))
所有查询都很顺利!
这个解决方案很糟糕!
另一种方法是使用 SQLQuery。 在我的例子中,以下代码工作正常:
区分是在数据库中完成的! 与以下情况相反:
在加载实体之后,在内存中完成区分!
NullPointerException
in some cases!Without
criteria.setProjection(Projections.distinct(Projections.property("id")))
all query goes well!
This solution is bad!
Another way is use SQLQuery. In my case following code works fine:
Distinction is done in data base! In opposite to:
where distinction is done in memory, after load entities!