如何通过连接和基于行的限制(分页)在hibernate中获得明显的结果?

Dan*_*iuc 69 java paging hibernate criteria distinct

我正在尝试使用基于行的限制(例如:setFirstResult(5)setMaxResults(10))在已连接到其他表的Hibernate Criteria查询上实现分页.

可以理解的是,数据随机被切断; 这里解释了原因.

作为解决方案,页面建议使用"第二个sql选择"而不是连接.

如何将现有条件查询(使用连接createAlias())转换为使用嵌套选择?

小智 103

您可以通过请求不同的ID列表而不是不同的水合对象列表来实现所需的结果.

只需将其添加到您的标准:

criteria.setProjection(Projections.distinct(Projections.property("id")));
Run Code Online (Sandbox Code Playgroud)

现在,您将根据基于行的限制获得正确数量的结果.这样做的原因是因为投影将执行清晰度检查作为 sql查询的一部分,而不是ResultTransformer 执行sql查询过滤清除结果的结果.

值得注意的是,您现在将获得一个id列表,而不是获取对象列表,您可以使用这些ID来稍后从休眠中对对象进行水合.

  • 这不适用于连接上的orderby (9认同)
  • FishBoy其实就是我.回到'08,你不能回答自己的问题. (5认同)
  • 你以后如何保湿这些物品? (3认同)

小智 43

我正在使用我的代码.

只需将其添加到您的标准:

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

该代码将类似于本机sql的select distinct*from table.希望这个有所帮助.

  • 在这种情况下这不起作用 - 请参阅FishBoy的答案解释原因. (13认同)
  • downvoted,因为这个答案是完全错误的,无论是在这个问题的背景下还是关于它的内容,如这里所解释的[http://stackoverflow.com/questions/25536868/criteria-distinct-root-entity-vs-projections-distinct ]**执行查询后,通过ResultSetTransformer完成此"distinct"** (4认同)
  • 另外,根据Daniel Alexiuc在他的问题中提供的链接,这并不总是转换为本机sql中的distinct子句.但如果您不需要分页,它确实有效. (2认同)
  • 简单错误的答案,不符合结果限制,投票的人不需要限制 (2认同)

Dan*_*iuc 26

根据FishBoy的建议略有改进.

可以在一次点击中进行这种查询,而不是在两个单独的阶段中进行.即,下面的单个查询将正确地分页不同的结果,并且还返回实体而不仅仅是ID.

只需使用带有id投影的DetachedCriteria作为子查询,然后在主Criteria对象上添加分页值.

它看起来像这样:

DetachedCriteria idsOnlyCriteria = DetachedCriteria.forClass(MyClass.class);
//add other joins and query params here
idsOnlyCriteria.setProjection(Projections.distinct(Projections.id()));

Criteria criteria = getSession().createCriteria(myClass);
criteria.add(Subqueries.propertyIn("id", idsOnlyCriteria));
criteria.setFirstResult(0).setMaxResults(50);
return criteria.list();
Run Code Online (Sandbox Code Playgroud)

  • 试过这个.不行.子查询可以工作,但主查询仍然不受"distinct"约束. (7认同)
  • 我认为这个答案更完整,并且真正填写了关于如何对关联对象的不同列表进行水合的答案。这正是我正在寻找的。谢谢你。真的,我认为这是最好的答案。 (2认同)

nik*_*ita 6

@ FishBoy建议的一个小改进是使用id投影,因此您不必对标识符属性名称进行硬编码.

criteria.setProjection(Projections.distinct(Projections.id()));
Run Code Online (Sandbox Code Playgroud)


小智 5

解决方案:

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
Run Code Online (Sandbox Code Playgroud)

效果很好。

  • 这适用于普通查询。但是这个问题专门询问使用“基于行的限制”或“分页”的 Hibernate 查询。 (6认同)