我有一个带有一些谓词的查询,我需要计算分页的总记录数。
目前,我正在做的是为查询声明2个根,以获得结果列表(1(和计数查询
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<A> cq = cb.createQuery(A.class);
Root<A> root = cq.from(A.class);
CriteriaQuery<Long> cq = cb.createQuery(A.class);
Root<A> rootCount = countQuery.from(A.class);
List<Predicate> predicates = new ArrayList<>();
List<Predicate> predicatesCount = new ArrayList<>();
Predicate p = cb.equal(root.get(A.ID), 1);
predicates.add(p);
Predicate p1 = cb.equal(rootCount.get(A.ID), 1);
predicatesCount.add(p1);
...
// execute both query to get result
所以问题是:
是否可以从查询(1(创建计数查询?或者使用计数查询重用谓词
感谢阅读!
下面的例子展示了设置一个标准构建器/谓词限制,然后重用它来执行计数查询。
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<EntityStub> criteriaQuery = builder.createQuery(EntityStub.class);
Root<EntityStub> entity_ = criteriaQuery.from(EntityStub.class);
entity_.alias("entitySub"); //assign alias to entity root
criteriaQuery.where(builder.equal(entity_.get("message"), "second"));
// Generic retrieve count
CriteriaQuery<Long> countQuery = builder.createQuery(Long.class);
Root<T> entity_ = countQuery.from(criteriaQuery.getResultType());
entity_.alias("entitySub"); //use the same alias in order to match the restrictions part and the selection part
countQuery.select(builder.count(entity_));
Predicate restriction = criteriaQuery.getRestriction();
if (restriction != null) {
countQuery.where(restriction); // Copy restrictions
}
Long count = entityManager.createQuery(countQuery).getSingleResult();
看看这是否对你有帮助,注意根别名,在进行计数查询时,确保Entity类类型是Long.class
https://forum.hibernate.org/viewtopic.php?p=2471522#p2471522
您可以使用Blaze Persistence为您生成计数查询,因为高效实现这样的计数查询并不容易。
Blaze Persistence是一个在JPA/Hibernate之上工作的库,它增加了对高级SQL构造的支持、丰富的分页支持等等。它还有一个JPACcriteria实现,您可以将其用作替换插件。然后,您可以将此查询转换为Blaze Persistence Core查询生成器,该查询生成器允许生成计数查询:https://github.com/Blazebit/blaze-persistence#jpa-标准api快速启动
我想这家伙用它的实用程序类回答了你的问题,比如:
Long count = JpaUtils.count(entityManager, criteriaQuery);
https://stackoverflow.com/a/9246377/5611906