Như những câu trả lời khác là đúng, nhưng quá đơn giản, vì vậy để hoàn chỉnh, tôi sẽ trình bày đoạn mã dưới đây để thực hiện SELECT COUNT
trên một truy vấn Tiêu chí JPA phức tạp (với nhiều phép nối, tìm nạp, điều kiện).
Nó được sửa đổi một chút câu trả lời này .
public <T> long count(final CriteriaBuilder cb, final CriteriaQuery<T> selectQuery,
Root<T> root) {
CriteriaQuery<Long> query = createCountQuery(cb, selectQuery, root);
return this.entityManager.createQuery(query).getSingleResult();
}
private <T> CriteriaQuery<Long> createCountQuery(final CriteriaBuilder cb,
final CriteriaQuery<T> criteria, final Root<T> root) {
final CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
final Root<T> 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<? extends Fetch<?, ?>> joins, Root<?> root) {
doJoins((Set<? extends Join<?, ?>>) joins, root);
}
private void doJoins(Set<? extends Join<?, ?>> 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<? extends Join<?, ?>> joins, Join<?, ?> root) {
for (Join<?, ?> join : joins) {
Join<?, ?> joined = root.join(join.getAttribute().getName(), join.getJoinType());
joined.alias(join.getAlias());
doJoins(join.getJoins(), joined);
}
}
Hy vọng nó tiết kiệm thời gian của ai đó.
Bởi vì IMHO JPA Criteria API không trực quan và cũng không dễ đọc.