[SPRING] 사양 및 Pageable을 함께 사용하는 경우 카운트를 비활성화하는 방법은 무엇입니까?
SPRING사양 및 Pageable을 함께 사용하는 경우 카운트를 비활성화하는 방법은 무엇입니까?
JpaSpecificationExecutor와 함께 제공되는 메서드는 부적절합니다. 그 중 아무 것도 내가 원하는 것을 제공하지 않습니다.
Page<T> findAll(Specification<T> spec, Pageable pageable)
List<T> findAll(Specification<T> spec)
List<T> findAll(Specification<T> spec, Sort sort)
첫 번째 방법은 페이지 매김 된 쿼리와 카운트 쿼리를 실행합니다. 다음 2는 페이지 매김을 전혀 수행하지 않습니다. 내가 필요로하는 것은 다음 중 하나입니다 :
Slice<T> findAll(Specification<T> spec, Pageable pageable)
List<T> findAll(Specification<T> spec, Pageable pageable)
JpaSpecificationExecutor를 확장하지 않음으로써 두 쿼리를 모두 실행할 수 있었지만 카운트 쿼리도 마찬가지였습니다. 제 상황에서는 카운트 쿼리가 매우 비싸기 때문에 피해야합니다. 문제는 어떻게?
해결법
-
==============================
1.SimpleJpaRepository의 findAll (Specification, Pageable) 및 readPage (TypedQuery, Pageable, Specification) 메소드를 살펴보십시오. Spring의 구현은 항상 count 쿼리를 수행하고 select 쿼리를 실행하기 전에 startIndex가 범위를 벗어나는 지 확인하는 것입니다.
SimpleJpaRepository의 findAll (Specification, Pageable) 및 readPage (TypedQuery, Pageable, Specification) 메소드를 살펴보십시오. Spring의 구현은 항상 count 쿼리를 수행하고 select 쿼리를 실행하기 전에 startIndex가 범위를 벗어나는 지 확인하는 것입니다.
protected Page<T> readPage(TypedQuery<T> query, Pageable pageable, Specification<T> spec) { query.setFirstResult(pageable.getOffset()); query.setMaxResults(pageable.getPageSize()); Long total = QueryUtils.executeCountQuery(getCountQuery(spec)); List<T> content = total > pageable.getOffset() ? query.getResultList() : Collections.<T> emptyList(); return new PageImpl<T>(content, pageable, total); }
나는 이것이 항상 최선의 방법이라고 생각하지 않는다. 예를 들어, 새로운 데이터가 카운트 업데이트를 보증 할만큼 자주 제공되지 않고 카운트 쿼리가 실행하는 데 많은 비용이 들기 때문에 카운트 쿼리를 한 번만 실행하면됩니다.
Spring Data가 단순한 찾기 쿼리와 유사하게 criteria 쿼리에 대한 카운트를 비활성화하는 플래그 또는 대체 방법을 제공 할 수 있다면 좋을 것입니다.
그 동안 내 해결 방법은 다음과 같습니다.
SimpleJpaRepository를 하위 클래스로하는 내부 클래스를 만듭니다. countPage를 비활성화하려면 readPage를 재정의하십시오. DAO를 만들고 @Repository로 주석을 달고이 내부 클래스를 인스턴스화하여 올바른 EntityManager를 전달하십시오. 마지막으로 "카운트 없음"기준 검색이 적용될 수있는 곳이면 어디든지이 DAO를 삽입하십시오.
@Repository public class CriteriaNoCountDao { @PersistenceContext protected EntityManager em; public <T, ID extends Serializable> Page<T> findAll(Specification<T> spec, Pageable pageable, Class<T> clazz){ SimpleJpaNoCountRepository<T, ID> noCountDao = new SimpleJpaNoCountRepository<T, ID>(clazz, em); return noCountDao.findAll(spec, pageable); } /** * Custom repository type that disable count query. */ public static class SimpleJpaNoCountRepository<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> { public SimpleJpaNoCountRepository(Class<T> domainClass, EntityManager em) { super(domainClass, em); } /** * Override {@link SimpleJpaRepository#readPage(TypedQuery, Pageable, Specification)} */ protected Page<T> readPage(TypedQuery<T> query, Pageable pageable, Specification<T> spec) { query.setFirstResult(pageable.getOffset()); query.setMaxResults(pageable.getPageSize()); List<T> content = query.getResultList(); return new PageImpl<T>(content, pageable, content.size()); } } }
-
==============================
2.해당 링크에 표시된대로 사용자 정의 기본 repositoy impl을 작성하십시오. https://www.baeldung.com/spring-data-jpa-method-in-all-repositories
해당 링크에 표시된대로 사용자 정의 기본 repositoy impl을 작성하십시오. https://www.baeldung.com/spring-data-jpa-method-in-all-repositories
다음과 같은 메소드를 작성하십시오.
public List<T> findAllBy(Specification<T> aSpecification, Pageable aPageable) { TypedQuery<T> query = getQuery(aSpecification, aPageable); query.setFirstResult((int) aPageable.getOffset()); query.setMaxResults(aPageable.getPageSize()); return query.getResultList(); }
from https://stackoverflow.com/questions/26738199/how-to-disable-count-when-specification-and-pageable-are-used-together by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 포트 80에서 Spring Boot 애플리케이션을 실행하려면 어떻게해야합니까? (0) | 2019.03.15 |
---|---|
[SPRING] Gradle을 사용하여 프로젝트에 AngularJs를 포함 할 수 있습니까? (0) | 2019.03.15 |
[SPRING] 최대 절전 모드, 스프링 및 SLF4J 바인딩 (0) | 2019.03.15 |
[SPRING] 왜 우리는 Data Jpa에서 질의를 위해 @Modifying 어노테이션을 사용해야 만 하는가? (0) | 2019.03.15 |
[SPRING] Spring Hibernate 템플릿은 오라클의 계산 쿼리에서 어떤 객체 유형을 반환합니까? (0) | 2019.03.15 |