正如其他的答案是正確的,但是過於簡單,所以爲了完整起見,我在下面的代碼片段中展示SELECT COUNT
的複雜的 JPA標準查詢(具有多個聯接,提取,條件)。
它稍作修改this answer。
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);
}
}
希望能節省一些人的時間。
因爲恕我直言,JPA Criteria API不直觀也不可讀。
這就是我已經想通自己,謝謝。但這意味着我不能使用相同的查詢實例來查詢結果數量和實際結果,我知道這些結果與SQL相似,但這會使此API更像OOP。那麼,我猜,至少我可以重用一些謂詞。 – 2010-05-21 18:34:48
@Barett如果它是一個相當大的數量,你可能不想將數百或數千個實體加載到內存中,只是爲了找出有多少實體! – Affe 2012-12-10 06:31:19
@Barett這是用於分頁的情況下。因此需要一個總數並且只有實際行的一個子集。 – gkephorus 2013-11-27 13:35:34