[ 김영한 스프링 데이터 JPA #4 ] 정렬과 페이징

김수호·2024년 6월 3일
0
post-thumbnail

스프링 데이터 JPA 는 정렬과 페이징을 구현하기 위한 다양한 편의 기능을 제공한다.

  • 페이징과 정렬을 위한 파라미터 지원
    • org.springframework.data.domain.Sort : 정렬 기능
    • org.springframework.data.domain.Pageable : 페이징 기능 ( 내부에 Sort 포함 )
    • 참고)
      • Pageable 은 인터페이스다. 따라서 실제 사용할 때는 해당 인터페이스를 구현한 org.springframework.data.domain.PageRequest 객체를 사용한다.
      • PageRequest 생성자의 첫 번째 파라미터에는 현재 페이지를, 두 번째 파라미터에는 조회할 데이터 수를 입력한다. 여기에 추가로 정렬 정보도 파라미터로 사용할 수 있다.
        • 주의) 참고로 페이지는 0 부터 시작한다.
        • ex) PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username"))
  • 특별한 반환 타입 지원
    • 반환 타입에 따라서 전체 count 조회 쿼리를 추가적으로 날릴 지 안날릴 지, 다음 페이지 여부를 체크할지 안할지 등이 결정된다.
      • org.springframework.data.domain.Page : 전체 count 조회 쿼리 결과를 포함하는 페이징
      • org.springframework.data.domain.Slice : 전체 count 조회 쿼리 없이 다음 페이지만 확인 가능
        • 내부적으로 (limit + 1) 을 넣어서 다음 페이지 여부를 체크한다.
      • List (자바 컬렉션): 추가 count 쿼리 없이 결과만 반환

 

✔️ 참고

  • 페이지를 유지하면서 엔티티를 DTO로 변환하기
    • 컨트롤러에서 API 응답으로 엔티티를 반환하면 안된다. DTO 로 변환해서 넘겨야 한다.
      • Pagemap() 을 지원해서 내부 데이터를 다른 것으로 변경할 수 있다.
  • 단순히 앞에서 3건만 조회하고 싶거나 하는 경우는 List<Member> findTop3ByAge(); 과 같은 쿼리 메소드 기능을 사용하면 된다. 굳이 페이징을 넘기거나 하지 않아도 된다.
  • 페이징 카운트 쿼리 분리
    • 실무에서 복잡하고 무거운 쿼리에서 페이징 처리를 할 때, 데이터 조회는 left join 등을 해서 조회하지만, 전체 카운트 조회시에는 그런 조인 관계가 필요없는 경우가 있다. ( 카운트 쿼리와 데이터 조회 쿼리가 다를 수 있다. )
    • 이런 경우에는, @Query 를 통해 카운트 쿼리를 분리할 수 있다.
      • 위 쿼리를 보면, 사실상 카운트 조회시에는 MemberTeam 을 조인할 필요가 없다. 따라서 @Query 를 통해 카운트 조회 쿼리를 분리했다.
      • 만약 위 @Query 에서 countQuery 를 작성하지 않으면, 전체 카운트 조회 시 left join 되는 것을 확인할 수 있다.
        • 참고) 스프링 부트 3 이상을 사용하면 하이버네이트 6이 적용된다. 이 경우 하이버네이트 6에서 의미없는 left join 을 최적화해버린다. 따라서 countQuery 를 작성하지 않았더라도, 전체 카운트 조회시 left join 을 하지 않는다. 그리고 데이터 조회시에도 조인을 했긴 했지만 Team 을 전혀 사용하지 않는다. 따라서 실제 SQL 로그를 확인해보면 조인하지 않는다.

강의를 듣고 정리한 글입니다. 코드와 그림 등의 출처는 김영한 강사님께 있습니다.

profile
현실에서 한 발자국

0개의 댓글