jpa从现有的criteriaquery创建count查询

q9yhzks0  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(785)

我有一个带有一些 predicate 的查询,我需要计算分页的总记录数。
目前,我要做的是为查询声明两个根,以获得结果列表(1)和计数查询(2),然后用每个 predicate 用不同的根复制它,如下所示

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)创建计数查询?或者用count查询重用 predicate ?
感谢阅读!

nwlqm0z1

nwlqm0z11#

下面的示例展示了如何设置条件生成器/ predicate 限制,然后重用该限制来执行计数查询。

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();

查看这是否有帮助,注意根别名,在执行计数查询时,确保实体类类型为long.class
https://forum.hibernate.org/viewtopic.php?p=2471522#p2471522

nimxete2

nimxete22#

您可以使用blaze persistence为您生成count查询,因为高效地实现这样的count查询并不是那么容易。
blazepersistence是一个在jpa/hibernate之上工作的库,它增加了对高级sql构造的支持、丰富的分页支持等等。它还有一个jpa标准实现,您可以使用它作为替代品。然后可以将此查询转换为blaze persistence core查询生成器,该生成器允许生成计数查询:https://github.com/blazebit/blaze-persistence#jpa-标准api快速入门

相关问题