我正在尝试实现以下便捷方法:
/**
* 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: …Run Code Online (Sandbox Code Playgroud) 我是JPA的新手,想要实现一个通用的JPA DAO,需要找到查询结果集的行数来实现分页.搜索网络后,我找不到切实可行的方法.以下是许多文章中建议的代码:
public <T> Long findCountByCriteria(CriteriaQuery<?> criteria) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Long> countCriteria = builder.createQuery(Long.class);
Root<?> entityRoot = countCriteria.from(criteria.getResultType());
countCriteria.select(builder.count(entityRoot));
countCriteria.where(criteria.getRestriction());
return em.createQuery(countCriteria).getSingleResult();
}
Run Code Online (Sandbox Code Playgroud)
但是,该代码在使用时不起作用join.有没有办法使用JPA Criteria API计算查询结果集的行数?
更新:这是创建CriteriaQuery的代码:
CriteriaQuery<T> queryDefinition = criteriaBuilder.createQuery(this.entityClass);
Root<T> root = queryDefinition.from(this.entityClass);
Run Code Online (Sandbox Code Playgroud)
并且可以将一些联接添加到根,直到执行查询为止:
public Predicate addPredicate(Root<T> root) {
Predicate predicate = getEntityManager().getCriteriaBuilder().ge(root.join(Entity_.someList).get("id"), 13);
return predicate;
}
Run Code Online (Sandbox Code Playgroud)
并且生成的异常如下:
org.hibernate.hql.ast.QuerySyntaxException:无效路径:'generatedAlias1.id'[从entity.Entity中选择count(generatedAlias0)为generatedAlias0,其中(generatedAlias0.id> = 13L)和((generatedAlias1.id <= 34L)) ]
其中generatedAlias1应该在Entity上,generatedAlias0应该在我加入的关联上.请注意,我正确实现了Join,因为当我执行不带计数查询的查询时,它执行时没有错误,并且Join正常工作但是当我尝试执行count查询时它会抛出异常.
我在 Hibernate5 和 JPA2 中使用 Java8。我想计算结果集中的行数。我有以下有效的代码,但是,我想知道是否有更有效的方法?我认为下面的代码首先查询整个结果集并计算行数。
final EntityManagerFactory entityManagerFactory = entityManager.getEntityManagerFactory();
final CriteriaBuilder criteriaBuilder = entityManagerFactory.getCriteriaBuilder();
CriteriaQuery<Rating> criteria = criteriaBuilder.createQuery(Rating.class);
Root<Rating> root = criteria.from(Rating.class);
ParameterExpression<Job> param = criteriaBuilder.parameter(Job.class);
TypedQuery<Rating> queryRating = entityManager.createQuery(criteria);
queryRating.setParameter(param, job);
int results = queryRating.getResultList().size();
Run Code Online (Sandbox Code Playgroud)
有没有办法让 SQL 做一个count(*)?
更新
感谢下面的@chsdk,我有一个修改后的代码版本:
CriteriaBuilder qb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> cq = qb.createQuery(Long.class);
cq.select(qb.count(cq.from(Rating.class)));
cq.where(/*your stuff*/);
return entityManager.createQuery(cq).getSingleResult();
Run Code Online (Sandbox Code Playgroud)
题
如何where使用Job参数设置子句?
更多信息:
+--------+ +------------+ +-----+
| rating | | rating_job | | job |
+--------+ +------------+ +-----+ …Run Code Online (Sandbox Code Playgroud) 我一直在尝试获取总行数并这样做,我使用了 JPA Criteria API,但它在Long count = em.createQuery(sc).getSingleResult();line处抛出错误并说java.lang.IllegalStateException: No criteria query roots were specified. 我做了一些研究,但无法缩小问题的范围。
这是我的代码片段;
@PersistenceContext
public EntityManager em;
......
public Page<UserDTO> findByCriteria(String filters, Pageable pageable) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<UserDTO> cq = cb.createQuery(UserDTO.class);
Root<UserDTO> iRoot = cq.from(UserDTO.class);
List<Predicate> predicates = new ArrayList<Predicate>();
if (StringUtils.isNotEmpty(filters)) {
predicates.add(cb.like(cb.lower(iRoot.<String>get("login")), "%" + filters.toLowerCase() + "%"));
}
Predicate[] predArray = new Predicate[predicates.size()];
predicates.toArray(predArray);
CriteriaQuery<Long> sc = cb.createQuery(Long.class);
sc.select(cb.count(iRoot));
sc.where(predArray);
Long count = em.createQuery(sc).getSingleResult();
cq.where(predArray);
List<Order> orders = new ArrayList<Order>(2); …Run Code Online (Sandbox Code Playgroud)