[5] 스프링 데이터 JPA (4) - 쿼리 메소드 기능 2 (페이징 / Page<>, Slice<>)

김정욱·2021년 4월 13일
1
post-thumbnail

순수 JPA 페이징 & 정렬

  • findByPage
    : 페이징을 하기 위한 offsetlimit을 받고, 정렬하기 위한 필드age를 받아 페이징 수행
  • totalCount
    : 보통 페이징을 하면서 전체 데이터의 수를 많이 쓰기 때문에 거의 함께 필요함
  • 실제 페이징을 하면서 다양한 정보들이 필요
    • 현재 페이지에 대한 정보
    • 마지막 페이지 정보
    • 최초 페이지 정보
    • 전체 데이터 수
    • 등등

스프링 데이터 JPA에서 페이징 & 정렬

[ 설명 ]

  • org.springframework.data
    : JPA종속적이지 않고 다양한 DB와도 호환 가능공통 인터페이스 부분
  • 사용하는 페이징정렬 파라미터
    : 페이징을 하기 위한 정보Pageable객체에 담아서 받게 된다
    • org.springframework.data.domain.Sort : 정렬
    • org.springframework.data.domain.Pageable : 페이징 (내부Sort 포함)
  • 제공하는 특별한 반환 타입
    • org.springframework.data.domain.Page : 추가 count 쿼리 결과를 포함하는 페이징
    • org.springframework.data.domain.Slice : 추가 count 쿼리 없이 다음 페이지만 확인 가능페이징
    • List<> : 일반적인 컬렉션 List

[ 사용 예시 - Page객체 ]

  • Page<Member>를 반환하며 agePageable 객체파라미터로 지정
  • PageRequest페이징에 필요한 offset / limit / sort지정하여 파라미터로 전달
    (PageRequestPageable구현체)
  • page.getTotalElements() : 전체 데이터 수 (count)
  • page.getNumber() : 현재 페이지 번호
  • page.getTotalPages() : 전체 페이지 번호
  • page.isFirst() : 첫 페이지인지 확인
  • page.hasNext() : 다음 페이지가 있는지 확인
  • Page객체를 통한 조회자동으로 전체 데이터 수 count를 구하는 쿼리생성된다

[ Count Query 최적화 ]

  • Page 반환타입지정할 경우 자동으로 추가 count 쿼리가 발생되는데 이 때문에 성능이 느려질 수 있다는 것알아둘 필요가 있다
  • 만약 Team의 정보도 함께 조회하는 상황이라면 join을 통한 쿼리가 실행되어야 하는데
    이 때, 묵시적으로 count queryjoin이 발생되는 것을 확인할 수 있다

    (count 쿼리에서는 해당하는 member의 수만 알면 되서 join이 불필요하다!)

  • count query직접 지정하면 이러한 성능 악화를 막을 수 있다
    (count query 작성시 반드시 반환타입이 Long이라서 count()를 해주는 것을 잊지 말자)


[ 사용 예시 - Slice객체 ]

  • 반환타입을 Slice<>로 명시하면 Page<>와 다르게 추가 count쿼리가 나가지 않는다
  • 대신 특별하게 우리가 조회하는 limit+1 만큼 조회를 수행
  • offset 0 / limit 3 으로 조회했지만 실제로는 limit+1만큼 조회가 수행
  • 더보기 버튼처럼 다음 페이지의 부분 정보를 활용하는 페이징 방식에서 사용
  • 추가 count를 구하는 쿼리수행되지 않기 때문에 해당 메서드는 존재하지 않음
    • page.getTotalElements() : 데이터의 총 개수
    • page.getTotalPages() : 페이지의 총 개수

[ DTO로 페이징 결과 받기 ]

  • Page / Slice 어느것을 쓰더라도 결과적으로 Entity 자체를 반환하면 안된다
  • Page<> / Slice<>그대로 DTO로 변환한 뒤 반환하면 문제가 되지 않는다. (.map() 사용)
profile
Developer & PhotoGrapher

0개의 댓글