blu*_*ubb 11 orm jpa count criteria-api jpa-2.0
我正在尝试实现以下便捷方法:
/**
* Counts the number of results of a search.
* @param criteria The criteria for the query.
* @return The number of results of the query.
*/
public int findCountByCriteria(CriteriaQuery<?> criteria);
Run Code Online (Sandbox Code Playgroud)
在Hibernate中,这是通过
criteria.setProjection(Projections.rowCount());
Run Code Online (Sandbox Code Playgroud)
JPA中的上述内容是什么?我找到了许多简单的计数示例,但没有一个使用了应该确定行数的CriteriaQuery.
编辑:
不幸的是我发现@Pascal的答案不正确.问题非常微妙,只有在使用连接时才显示:
// Same query, but readable:
// SELECT *
// FROM Brain b
// WHERE b.iq = 170
CriteriaQuery<Person> query = cb.createQuery(Person.class);
Root<Person> root = query.from(Person.class);
Join<Object, Object> brainJoin = root.join("brain");
Predicate iqPredicate = cb.equal(brainJoin.<Integer>get("iq"), 170);
query.select(root).where(iqPredicate);
Run Code Online (Sandbox Code Playgroud)
在调用时findCountByCriteria(query),它会因以下异常而死亡:
org.hibernate.hql.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.iq' [select count(generatedAlias0) from xxx.tests.person.dom.Person as generatedAlias0 where generatedAlias1.iq=170]
Run Code Online (Sandbox Code Playgroud)
还有其他方法可以提供这样的CountByCriteria方法吗?
Jos*_*tin 17
我写了一个实用程序类, JDAL JpaUtils来做它:
Long count = JpaUtils.count(em, criteriaQuery);JpaUtils.copyCriteria(em, criteriaQueryFrom, criteriaQueryTo);CriteriaQuery<Long> countCriteria = JpaUtils.countCriteria(em, criteria)等等...
如果您对源代码感兴趣,请参阅JpaUtils.java
我已经使用 cb.createQuery() (没有结果类型参数)对此进行了整理:
public class Blah() {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery query = criteriaBuilder.createQuery();
Root<Entity> root;
Predicate whereClause;
EntityManager entityManager;
Class<Entity> domainClass;
... Methods to create where clause ...
public Blah(EntityManager entityManager, Class<Entity> domainClass) {
this.entityManager = entityManager;
this.domainClass = domainClass;
criteriaBuilder = entityManager.getCriteriaBuilder();
query = criteriaBuilder.createQuery();
whereClause = criteriaBuilder.equal(criteriaBuilder.literal(1), 1);
root = query.from(domainClass);
}
public CriteriaQuery<Entity> getQuery() {
query.select(root);
query.where(whereClause);
return query;
}
public CriteriaQuery<Long> getQueryForCount() {
query.select(criteriaBuilder.count(root));
query.where(whereClause);
return query;
}
public List<Entity> list() {
TypedQuery<Entity> q = this.entityManager.createQuery(this.getQuery());
return q.getResultList();
}
public Long count() {
TypedQuery<Long> q = this.entityManager.createQuery(this.getQueryForCount());
return q.getSingleResult();
}
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你 :)
我所做的是类似于 CriteriaBuilder 的构建器,您可以在其中构建查询并使用相同的条件限制调用 list() 或 count()