【问题标题】:Pagination with Hibernate criteria and FetchMode.JOIN使用 Hibernate 标准和 FetchMode.JOIN 进行分页
【发布时间】:2011-09-15 23:50:51
【问题描述】:

我有两张表,“Players”和“Items”。玩家有一个物品清单。我想使用分页检索玩家及其所有物品。我想根据玩家进行分页,而不考虑有多少项目。

所以我做了这样的事情:

Criteria c = session.createCriteria(Players.class).setFetchMode("items", FetchMode.JOIN);
c.addOrder(Order.asc("playerID"));
c.setFirstResult(0);
c.setMaxResults(25);
List<Player> players = c.list();

这是给我前 25 个玩家,还是给我前 25 个物品(按玩家分组)?我想知道这种行为是否像 JPA 查询那样是未定义的,或者是否有保证的答案。

无论如何,哪些条件查询会给我前 25 个玩家或前 25 个玩家-物品组合(按玩家 ID,然后是物品 ID)?

【问题讨论】:

  • 这不是 HQL。我改了标题。

标签: hibernate hibernate-criteria


【解决方案1】:

来自 Hibernate 的“高级问题”常见问题解答:

http://community.jboss.org/wiki/HibernateFAQ-AdvancedProblems

原因也应该很明显 结果集基于行的“限制” 操作,例如 setFirstResult(5) 和 setMaxResults(10) 不起作用 有了这些急切的取物 查询。如果将结果集限制为 一定数量的行,你切断 数据随机。有一天休眠可能 要足够聪明,知道如果你 调用 setFirstResult() 或 setMaxResults() 它不应该使用 加入,但第二个 SQL SELECT。试试吧, 你的 Hibernate 版本可能 已经足够聪明了。如果没有,请写 两个查询,一个用于限制内容, 另一个用于渴望获取。

换句话说,Hibernate 不支持这一点。如果您更聪明并且知道 Hibernate 是如何实现的,那么很明显 setFirstResult 和 setMaxResults 在所有情况下都不会像分页一样远程执行任何操作。很明显,不需要记录。

【讨论】:

    【解决方案2】:

    非常肯定,但不是 100%,它将执行以下操作:

    它将加入玩家和物品,按玩家ID排序并获取前25个结果,所有这些都在一个SQL查询中。根据这些数据,它会创建玩家和物品,这将导致任意数量的玩家(小于或等于 25)总共有 25 个物品。最后一个玩家可能没有拿到所有物品。

    要获得25名玩家,请避免FetchMode.JOIN(为避免N+1问题,在映射文件中使用batch-size):

    List<Player> first25Players = session
      .createCriteria(Players.class)
      .addOrder(Order.asc("playerID"))
      .setMaxResults(25)
      .list();
    

    要获得 25 个项目,请按项目而不是玩家开始查询。

    List<Item> first25Items = session
      .createCriteria(Item.class)
      .addOrder(Order.asc("player")) // assuming that player is available
      .setMaxResults(25)
      .list();
    

    如果没有从项目到播放器的导航,您可以添加一个。

    【讨论】:

      猜你喜欢
      • 2012-06-17
      • 2015-03-15
      • 1970-01-01
      • 1970-01-01
      • 2013-08-14
      • 2013-12-10
      • 2017-03-27
      • 1970-01-01
      • 2013-11-06
      相关资源
      最近更新 更多