Spring Data JPA, 페이징과 정렬

Yebali·2021년 7월 28일
0

Spring Data JPA는 페이징과 정렬이 공통화 되어있다.

페이징과 정렬 파라미터

  • org.springframework.data.domain.Sort : 정렬기능
  • org.springframework.data.domain.Pageable : 페이징 기능(내부에 Sort를 포함)

특별한 반환 타입

  • org.springframework.data.domain.Page : 추가 count 쿼리 결과를 포함하는 페이징
  • org.springframework.data.domain.Slice : 추가 count 쿼리 없이 다음 페이지만 확인 가능 (내부적으로 limit + 1조회)
  • List (자바 컬렉션): 추가 count 쿼리 없이 결과만 반환

페이징과 정렬 사용 예시

Page<Member> findByUsername(String name, Pageable pageable);  //count 쿼리 사용
Slice<Member> findByUsername(String name, Pageable pageable); //count 쿼리 사용 안함
List<Member> findByUsername(String name, Pageable pageable);  //count 쿼리 사용 안함
List<Member> findByUsername(String name, Sort sort);

Page 사용 예제 코드

@Test
public void page() throws Exception {

      memberRepository.save(new Member("member1", 10));
      memberRepository.save(new Member("member2", 10));
      memberRepository.save(new Member("member3", 10));
      memberRepository.save(new Member("member4", 10));
      memberRepository.save(new Member("member5", 10));

      PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username"));
      Page<Member> page = memberRepository.findByAge(10, pageRequest);

      List<Member> content = page.getContent(); //조회된 데이터
      assertThat(content.size()).isEqualTo(3); //조회된 데이터 수 
      assertThat(page.getTotalElements()).isEqualTo(5); //전체 데이터 수 
      assertThat(page.getNumber()).isEqualTo(0); //페이지 번호
      assertThat(page.getTotalPages()).isEqualTo(2); //전체 페이지 번호 
      assertThat(page.isFirst()).isTrue(); //첫번째 항목인가? 
      assertThat(page.hasNext()).isTrue(); //다음 페이지가 있는지
}

'PageRequest'는 'Pageble'인터페이스를 구현한 인터페이스이다.
Page는 1이 아닌 0부터 시작한다.

참고

  1. Count Query를 별도로 최적화해야 할 경우 아래와 같이 별도로 선언해서 사용해도 된다.
    복잡한 쿼리에서 countQuery는 굳이 left join의 결과의 count를 볼 필요가 없기 때문에 별도로 분리하는게 좋다.
@Query(value = "select m from Member m left join m.team t", countQuery = "select count(m) from Member m")
Page<Member> findByAge(int age, Pageable pageable);
  1. 페이지를 유지하면서 엔티티를 DTO로 변환하기.
    엔티티를 그대로 반환하는 것은 좋지 않기 때문에 DTO로 변환하여 반환하는 것이 좋다.
Page<Member> page = memberRepository.findByAge(10, pageRequest);
Page<MemberDto> dtoPage = page.map(m -> new MemberDto());
profile
머리에 다 안들어가서 글로 적는 중

0개의 댓글