如何计算一般JPA DAO中JPA 2 CriteriaQuery的行数?

前端之家收集整理的这篇文章主要介绍了如何计算一般JPA DAO中JPA 2 CriteriaQuery的行数?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我是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();
}

但是,使用join时该代码不起作用.有没有办法使用JPA Criteria API计算查询结果集的行数?

更新:
这是创建CriteriaQuery的代码

CriteriaQuery<T> queryDefinition = criteriaBuilder.createQuery(this.entityClass);
    Root<T> root = queryDefinition.from(this.entityClass);

并且可以将一些联接添加到根,直到执行查询为止:

public Predicate addPredicate(Root<T> root) {
                Predicate predicate = getEntityManager().getCriteriaBuilder().ge(root.join(Entity_.someList).get("id"),13);
                return predicate;
}

并且生成的异常如下:

org.hibernate.hql.ast.QuerySyntaxException: Invalid path:
‘generatedAlias1.id’ [select count(generatedAlias0) from entity.Entity
as generatedAlias0 where ( generatedAlias0.id>=13L ) and (
(generatedAlias1.id<=34L ) )]

其中generatedAlias1应该在Entity上,generatedAlias0应该在我加入的关联上.
请注意,我正确实现了Join,因为当我执行不带计数查询查询时,它执行时没有错误,并且Join正常工作但是当我尝试执行count查询时它会抛出异常.

解决方法

我这样做了:
public Long getRowCount(CriteriaQuery criteriaQuery,CriteriaBuilder criteriaBuilder,Root<?> root){
    CriteriaQuery<Long> countCriteria = criteriaBuilder.createQuery(Long.class);
    Root<?> entityRoot = countCriteria.from(root.getJavaType());
    entityRoot.alias(root.getAlias());
    doJoins(root.getJoins(),entityRoot);
    countCriteria.select(criteriaBuilder.count(entityRoot));
    countCriteria.where(criteriaQuery.getRestriction());
    return this.entityManager.createQuery(countCriteria).getSingleResult();
}

private void doJoins(Set<? extends Join<?,?>> joins,Root<?> root_){
    for(Join<?,?> join: joins){
        Join<?,?> joined = root_.join(join.getAttribute().getName(),join.getJoinType());
        doJoins(join.getJoins(),joined);
    }
}

private void doJoins(Set<? extends Join<?,Join<?,?> root_){
    for(Join<?,joined);
    }
}

当然,您不需要Root作为输入参数,您可以从条件查询获取它,

原文链接:https://www.f2er.com/java/122371.html

猜你在找的Java相关文章