JPA渴望获取和分页最佳实践

时间:2018-12-01 10:32:13

标签: jpa pagination jpql eager

经过一些研究,我发现了很多有关如何编写简单有效的代码(使用JPQL)的材料:

  1. 允许渴望获取相关实体(例如,使用JOIN FETCH)。
  2. 允许在单个实体上分页。

但是要将两者结合在一起-尚不清楚如何以有效且干净的方式进行操作。

  • 这是一种渴望获取的方法,但是分页已在内存中应用(又名 HHH000104:用集合fetch指定的firstResult / maxResults;在内存中应用!

    < / li>
  • 这是分页有效的方法,但急切的获取却不可行(即使resultSet实际上包含相关实体),也导致对数据库的附加查询,以获取数据库中每一行的相关实体


最有效的方法是 https://vladmihalcea.com/fix-hibernate-hhh000104-entity-fetch-pagination-warning-message/

但这让我想知道是否有更直观,更干净的解决方案?

问题:是否还有其他最佳实践,可用于如何在分页中快速获取相关实体?

注意:解决方案还应该提供一种将过滤器应用于从数据库中检索到的数据的方法。 (例如 JPQL WHERE子句

1 个答案:

答案 0 :(得分:2)

此问题的最简单方法是使用两个查询:

  1. 第一个应用 where 条件和分页的查询。查询仅返回ID
  2. 第二个查询,您使用第一个查询返回的ID,并在相关实体上设置FETCH

例如,第一个查询:

String jpql = "SELECT user.id FROM User user WHERE user.name = 'John'"

Query q = em.createQuery(jpql); 
q.setFirstResult(0);
q.setMaxResults(10);

List<Long> ids = q.getResultList();

第二个查询:

String jqpl = "SELECT user FROM User user JOIN FETCH user.address WHERE user.id IN (:ids)"
Query q = em.createQuery(jpql); 
q.setParameter("ids", ids);

List<User> users = q.getResultList();

如果需要排序依据某些列,请注意。 order by子句需要出现在两个查询中,因为数据库不遵守您在数据库返回行时通过参数传递的id顺序。