JPA 2에서 CriteriaQuery를 사용하여 결과를 카운트하는 방법
저는 JPA 2에 익숙하지 않습니다.Criteria Builder / CriteriaQuery API:
CriteriaQuery 결과를 실제로 검색하지 않고 카운트하고 싶습니다.그런 방법은 찾을 수 없었습니다만, 이 방법밖에 없습니다.
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<MyEntity> cq = cb
.createQuery(MyEntityclass);
// initialize predicates here
return entityManager.createQuery(cq).getResultList().size();
그리고 그건 적절한 방법이 아니야...
해결책이 있을까요?
유형의 쿼리MyEntity
돌아온다MyEntity
에 대한 쿼리를 원하십니까?Long
.
CriteriaBuilder qb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> cq = qb.createQuery(Long.class);
cq.select(qb.count(cq.from(MyEntity.class)));
cq.where(/*your stuff*/);
return entityManager.createQuery(cq).getSingleResult();
이 예에서 생략한 제한 및 그룹화 등을 사용하여 표현식을 구축하고 싶은 것은 분명합니다.
cb.create를 사용하여 이 문제를 해결했습니다.Query() (result type 파라미터 없음):
public class Blah() {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery query = criteriaBuilder.createQuery();
Root<Entity> root;
Predicate whereClause;
EntityManager entityManager;
Class<Entity> domainClass;
... Methods to create where clause ...
public Blah(EntityManager entityManager, Class<Entity> domainClass) {
this.entityManager = entityManager;
this.domainClass = domainClass;
criteriaBuilder = entityManager.getCriteriaBuilder();
query = criteriaBuilder.createQuery();
whereClause = criteriaBuilder.equal(criteriaBuilder.literal(1), 1);
root = query.from(domainClass);
}
public CriteriaQuery<Entity> getQuery() {
query.select(root);
query.where(whereClause);
return query;
}
public CriteriaQuery<Long> getQueryForCount() {
query.select(criteriaBuilder.count(root));
query.where(whereClause);
return query;
}
public List<Entity> list() {
TypedQuery<Entity> q = this.entityManager.createQuery(this.getQuery());
return q.getResultList();
}
public Long count() {
TypedQuery<Long> q = this.entityManager.createQuery(this.getQueryForCount());
return q.getSingleResult();
}
}
도움이 되었으면 좋겠다:)
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
cq.select(cb.count(cq.from(MyEntity.class)));
return em.createQuery(cq).getSingleResult();
다른 답은 맞지만 너무 단순하기 때문에 완성도를 높이기 위해 아래에 코드 스니펫을 제시합니다.SELECT COUNT
고도의 JPA Criteria 쿼리(복수의 Join, fetch, 조건 포함)에 대해 설명합니다.
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);
}
}
누군가의 시간을 절약해 주길 바라.
IMHO JPA Criteria API는 직관적이지도 않고 읽기 쉽지도 않기 때문입니다.
사용하는 JPA 2의 실장에 따라서는 조금 까다롭지만, 이것은 EclipseLink 2.4.1에서는 동작하지만 Hibernate에서는 동작하지 않습니다.여기 EclipseLink의 일반적인 CriteriaQuery 카운트는 다음과 같습니다.
public static Long count(final EntityManager em, final CriteriaQuery<?> criteria)
{
final CriteriaBuilder builder=em.getCriteriaBuilder();
final CriteriaQuery<Long> countCriteria=builder.createQuery(Long.class);
countCriteria.select(builder.count(criteria.getRoots().iterator().next()));
final Predicate
groupRestriction=criteria.getGroupRestriction(),
fromRestriction=criteria.getRestriction();
if(groupRestriction != null){
countCriteria.having(groupRestriction);
}
if(fromRestriction != null){
countCriteria.where(fromRestriction);
}
countCriteria.groupBy(criteria.getGroupList());
countCriteria.distinct(criteria.isDistinct());
return em.createQuery(countCriteria).getSingleResult();
}
얼마 전 Eclipse Link에서 Hibernate로 이행하여 카운트 기능을 다음과 같이 변경해야 했기 때문에, 이것은 해결하기 어려운 문제일 수 있습니다.이것은 Hibernate 4.x 이후부터 사용되고 있습니다.어느 쪽이 루트인지 추측하려고 하지 않기 때문에, 해결된 쿼리에서 패스합니다.o 추측하기 어려운 코너 케이스가 많이 있습니다.
public static <T> long count(EntityManager em,Root<T> root,CriteriaQuery<T> criteria)
{
final CriteriaBuilder builder=em.getCriteriaBuilder();
final CriteriaQuery<Long> countCriteria=builder.createQuery(Long.class);
countCriteria.select(builder.count(root));
for(Root<?> fromRoot : criteria.getRoots()){
countCriteria.getRoots().add(fromRoot);
}
final Predicate whereRestriction=criteria.getRestriction();
if(whereRestriction!=null){
countCriteria.where(whereRestriction);
}
final Predicate groupRestriction=criteria.getGroupRestriction();
if(groupRestriction!=null){
countCriteria.having(groupRestriction);
}
countCriteria.groupBy(criteria.getGroupList());
countCriteria.distinct(criteria.isDistinct());
return em.createQuery(countCriteria).getSingleResult();
}
투영을 사용할 수도 있습니다.
ProjectionList projection = Projections.projectionList();
projection.add(Projections.rowCount());
criteria.setProjection(projection);
Long totalRows = (Long) criteria.list().get(0);
Spring Data Jpa에서는 다음 방법을 사용할 수 있습니다.
/*
* (non-Javadoc)
* @see org.springframework.data.jpa.repository.JpaSpecificationExecutor#count(org.springframework.data.jpa.domain.Specification)
*/
@Override
public long count(@Nullable Specification<T> spec) {
return executeCountQuery(getCountQuery(spec, getDomainClass()));
}
언급URL : https://stackoverflow.com/questions/2883887/in-jpa-2-using-a-criteriaquery-how-to-count-results
'programing' 카테고리의 다른 글
mappedBy 알 수 없는 대상 엔티티 속성 (0) | 2022.10.26 |
---|---|
Java 메서드에서 불필요한 반환을 방지하려면 어떻게 해야 합니까? (0) | 2022.10.26 |
python의 바이트 배열에 대한 16진수 문자열 (0) | 2022.10.26 |
랜덤 (Java 7)의 181783497276652981 및 8682522807148012는 무엇입니까? (0) | 2022.10.26 |
이미 데이터가 포함된 MariaDB 테이블에 키를 추가하려면 어떻게 해야 합니까? (0) | 2022.10.26 |