使用JPA Criteria API进行分页的总行数

我正在为我的系统中的实体实现“高级搜索”类function,以便用户可以使用此实体的属性上的多个条件(eq,ne,gt,lt等)搜索该实体。 我正在使用JPA的Criteria API动态生成Criteria查询,然后使用setFirstResult()setMaxResults()来支持分页。 一切都很好,直到这一点,但现在我想显示结果网格上的结果总数,但我没有看到直接的方式来获得Criteria查询的总计数。
这就是我的代码的样子:

 CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery cQuery = builder.createQuery(Brand.class); Root from = cQuery.from(Brand.class); CriteriaQuery select = cQuery.select(from); . . //Created many predicates and added to **Predicate[] pArray** . . select.where(pArray); // Added orderBy clause TypedQuery typedQuery = em.createQuery(select); typedQuery.setFirstResult(startIndex); typedQuery.setMaxResults(pageSize); List resultList = typedQuery.getResultList(); 

我的结果集可能很大,所以我不想加载我的实体进行计数查询,所以请告诉我在Criteria上获取像rowCount()方法这样的总计数的有效方法(我认为它在Hibernate的Criteria中)。

谢谢弗拉基米尔! 我接受了你的想法,并使用单独的计数查询来使用我现有的谓词数组。 最终实现如下:

 CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery cQuery = builder.createQuery(Brand.class); Root from = cQuery.from(Brand.class); CriteriaQuery select = cQuery.select(from); . . //Created many predicates and added to **Predicate[] pArray** . . CriteriaQuery cq = builder.createQuery(Long.class); cq.select(builder.count(cq.from(Brand.class))); // Following line if commented causes [org.hibernate.hql.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.enabled' [select count(generatedAlias0) from xxx.yyy.zzz.Brand as generatedAlias0 where ( generatedAlias1.enabled=:param0 ) and ( lower(generatedAlias1.description) like :param1 )]] em.createQuery(cq); cq.where(pArray); Long count = em.createQuery(cq).getSingleResult(); . . select.where(pArray); . . // Added orderBy clause TypedQuery typedQuery = em.createQuery(select); typedQuery.setFirstResult(startIndex); typedQuery.setMaxResults(pageSize); List resultList = typedQuery.getResultList() 

虽然这个工作正常,但我仍然不确定为什么要写

 em.createQuery(cq); 

让它工作。 任何想法?

你为什么不用伯爵?

 CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery cQuery = builder.createQuery(Long.class); Root from = cQuery.from(Brand.class); CriteriaQuery select = cQuery.select(builder.count(from)); . . //Created many predicates and added to **Predicate[] pArray** . . select.where(pArray); // Added orderBy clause TypedQuery typedQuery = em.createQuery(select); typedQuery.setFirstResult(startIndex); //typedQuery.setMaxResults(pageSize); // here is the size of your query Long result = typedQuery.getSingleResult(); 

如果您正在使用Hibernate,因为您的JPA-Provider会查看投影 ,尤其是Projections.rowCount()

您可能必须执行两次查询,首先获取计数然后获取结果。

请注意,对于普通JPA,您可能需要一些其他方法。