In JPA 2, using a CriteriaQuery, how to count results

前端 未结 7 1143
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-28 19:28

I am rather new to JPA 2 and it\'s CriteriaBuilder / CriteriaQuery API:

CriteriaQuery javadoc

CriteriaQuery in the Java EE 6 tutorial

I would like to

7条回答
  •  一向
    一向 (楼主)
    2020-11-28 20:08

    As others answers are correct, but too simple, so for completeness I'm presenting below code snippet to perform SELECT COUNT on a sophisticated JPA Criteria query (with multiple joins, fetches, conditions).

    It is slightly modified this answer.

    public  long count(final CriteriaBuilder cb, final CriteriaQuery selectQuery,
            Root root) {
        CriteriaQuery query = createCountQuery(cb, selectQuery, root);
        return this.entityManager.createQuery(query).getSingleResult();
    }
    
    private  CriteriaQuery createCountQuery(final CriteriaBuilder cb,
            final CriteriaQuery criteria, final Root root) {
    
        final CriteriaQuery countQuery = cb.createQuery(Long.class);
        final Root countRoot = countQuery.from(criteria.getResultType());
    
        doJoins(root.getJoins(), countRoot);
        doJoinsOnFetches(root.getFetches(), countRoot);
    
        countQuery.select(cb.count(countRoot));
        countQuery.where(criteria.getRestriction());
    
        countRoot.alias(root.getAlias());
    
        return countQuery.distinct(criteria.isDistinct());
    }
    
    @SuppressWarnings("unchecked")
    private void doJoinsOnFetches(Set> joins, Root root) {
        doJoins((Set>) joins, root);
    }
    
    private void doJoins(Set> joins, Root root) {
        for (Join join : joins) {
            Join joined = root.join(join.getAttribute().getName(), join.getJoinType());
            joined.alias(join.getAlias());
            doJoins(join.getJoins(), joined);
        }
    }
    
    private void doJoins(Set> joins, Join root) {
        for (Join join : joins) {
            Join joined = root.join(join.getAttribute().getName(), join.getJoinType());
            joined.alias(join.getAlias());
            doJoins(join.getJoins(), joined);
        }
    }
    

    Hope it saves somebody's time.

    Because IMHO JPA Criteria API is not intuitive nor quite readable.

提交回复
热议问题