Yebali

Spring Data JPA의 페이징과 정렬 본문

Spring

Spring Data JPA의 페이징과 정렬

예발이 2021. 10. 11. 22:01

페이징과 정렬

Spring Data JPA가 제공하는 페이징과 정렬 기능은 아래처럼 사용 할 수 있다.

@GetMapping("/members")
public Page<Member> list(Pageable pageable) {
    Page<Member> page = memberRepository.findAll(pageable);
    return page;
}

파라미터로 "Pageable"을 받을 수 있다.
여기서 Pageable은 인터페이스이고, 구현체는 org.springframework.data.domain.PageRequest이다.

요청 파라미터

Pageable을 사용하는 URL에는 다음과 같은 요청 파라미터를 사용할 수 있다.

/members?page=0&size=3&sort=id,desc&sort=username,desc
  • page : 현재 페이지, 0부터 시작한다
  • size : 한 페이지에 노출할 데이터 갯수
  • sort : 정렬 조건을 정의.

페이지 갯수 설정

요청 파라미터에 size가 없을 경우를 위한 default 값 설정.

글로벌 설정

spring.data.web.pageable.default-page-size=20 # 기본 페이지 사이즈
spring.data.web.pageable.max-page-size=2000 # 최대 페이지 사이즈

개별 설정

@RequestMapping(value = "/members_page", method = RequestMethod.GET)
public String list(@PageableDefault(size = 12, sort = “username”,
                   direction = Sort.Direction.DESC) Pageable pageable) {
     ... 
}

페이징 접두사

만약 페이징 정보(Pageable)가 2개 이상일때는 어떻게 처리할까?
그때는 @Qualifier 애너테이션에 접두사를 사용하여 구분한다.

 

그리고 아래처럼 "[접두사명]_xxxx" 으로 요청을 보낸다
ex) member_page, member_size

/members?member_page=0&order_page=1

위의 요청을 Controller에서는 다음과 같이 처리한다.

public String list(
      @Qualifier("member") Pageable memberPageable,
      @Qualifier("order") Pageable orderPageable) {
      
}

Page내용을 DTO로 변환하기

Spring Data JPA에서 제공하는 페이징 기능을 사용하면 'Page' 객체에 담겨 반환된다.

Page 역시 내부에 Entity를 가지고 있기 때문에 API로 그대로 노출하면 다양한 문제가 발생한다.
그렇게 때문에 Page도 DTO로 변환해서 반환 하는 것을 권장한다.
Page는 map()을 지원해서 내부 데이터를 다른 것으로 변경 할 수 있다.

@GetMapping("/members")
public Page<MemberDto> list(Pageable pageable) {
    Page<Member> page = memberRepository.findAll(pageable);
    Page<MemberDto> pageDto = page.map(MemberDto::new);
    return pageDto;
}