스프링 데이터 JPA와 QueryDSL

사용자 정의 리포지토리

  • Spring Data JPA를 사용하려면 아래와 같이 작성해야 한다.

public interface MemberRepository extends JpaRepository<Member, Long> {
  List<Member> findByUsername(String username);
 }
  • 만약 QueryDSL로 원하는 메서드가 동작하도록 하기 위해서는 사용자 정의 리포지토리를 만들어 직접 구현 코드를 작성해야 한다.

  • 재사용 가능성이 많은 메서드의 경우 다음과 같이 인터페이스와 구현체를 둔다.

  • 사용자 정의 인터페이스

  • 사용자 정의 인터페이스의 구현체

  • 사용자 정의 인터페이스를 상속받아 MemberRepository만 주입받아도 사용 가능하도록 한다.


  • 만약 재사용 가능성이 적은 경우 별도 Repository 클래스를 구현해 주입받아 사용해도 된다.

QueryDSL 페이징 연동

  • 스프링 데이터의 Page, Pageable을 활용하는 방법을 알아본다.

데이터 내용과 전체 카운트를 한번에 조회하는 방법

  • 다음은 지정한 offset부터 limit 개수만큼의 데이터를 조회하는 로직이다.

  • 카운트 쿼리를 따로 작성하지 않아도 fetchResult.getTotal() 메서드를 호출하면 자동으로 카운트 쿼리가 날아가 데이터를 얻을 수 있다.

  • fetch() vs fetchResults()

    • fetchResults를 사용하면 fetch(), fetchCount() 정보를 모두 얻을 수 있다.

    • count 쿼리를 최적화하려면 fetchResults() 대신 fetch(), fetchCount()를 각각 구현하는 것이 좋다.

데이터 내용과 전체 카운트를 별도로 조회하는 방법

  • 다음은 fetch()와 fetchCount()를 구분하여 작성한 로직이다.

CountQuery 최적화

  • PageImpl 대신 PageableExecutionUtils.getPage() 를 반환해주면, count 쿼리가 생략 가능한 경우 쿼리가 날라가지 않도록 할 수 있다.

    • 페이지 시작이면서 컨텐츠 사이즈가 페이지 사이즈보다 작을 경우 count 쿼리 생략 가능

    • 마지막 페이지일 경우 offset + 컨텐츠 사이즈를 더해서 전체 사이즈를 구할 수 있음

스프링 데이터 정렬

  • 페이징의 정렬 조건을 Querydsl의 정렬 조건으로 직접 전환할 수 있다.

  • 하지만 단일 엔티티의 경우만 가능하므로 사실상 잘 사용되지 않는다.

QueryDSL 지원 클래스 직접 생성

  • QuerydslRepositorySupport 가 지닌 한계를 극복하기 위해 직접 Querydsl 지원 클래스를 만든다.

  • 스프링 데이터가 제공하는 페이징을 편리하게 QueryDSL로 변환할 수 있다.

  • 페이징과 카운트 쿼리 분리 가능

  • 스프링 데이터 Sort 지원

  • from()이 아니라 select() , selectFrom() 으로 시작 가능

  • EntityManager , QueryFactory 제공

직접 생성한 지원 클래스

fetchResults() , fetchCount() 지원 중단

  • count 정보를 얻으려면 select절에 count를 얻음을 명시한 후, 하나의 응답 결과만 받는 fetchOne()을 사용해야 한다.

Last updated