繁体   English   中英

JPA 从现有的 CriteriaQuery 创建计数查询

[英]JPA create count query from existing CriteriaQuery

我有一个带有一些谓词的查询,我需要计算分页的总记录。

目前,我正在做的是为查询声明 2 个根以获取结果列表(1)和计数查询(2) ,然后对于每个谓词,用不同的根复制它,如下所示

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

看看这是否对您有帮助,记下根别名,并在进行计数查询时,确保实体 class 类型为 Long.class

https://forum.hibernate.org/viewtopic.php?p=2471522#p2471522

您可以使用 Blaze-Persistence 为您生成计数查询,因为有效地实现这样的计数查询并不容易。

Blaze-Persistence 是一个在 JPA/Hibernate 之上工作的库,并增加了对高级 SQL 结构的支持、丰富的分页支持等等。 它还有一个 JPA Criteria 实现,您可以将其用作替代品。 然后,您可以将此查询转换为允许生成计数查询的 Blaze-Persistence Core 查询构建器: https://github.com/Blazebit/blaze-persistence#jpa-criteria-api-quick-start

我认为这个人用它的实用程序 class 回答了你的问题,如下所示:

Long count = JpaUtils.count(entityManager, criteriaQuery);

https://stackoverflow.com/a/9246377/5611906

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM