article thumbnail image
Published 2022. 9. 1. 20:13

JPA Paging 이란?

 

DB에 저장된 Entity들을 페이지로 나누는 것이다.
예를들어, DB에 책이 20권 저장되어있다.
프론트에서 "DB에 있는 책을 5권씩 분류해서, 두 번째 파트를 줘!" 라고 요청한다.
그러면 백엔드에서는 5권씩 분류하고, 분류된 책들의 두 번째 파트를 프론트에게 넘겨준다.
위 상황과 같이, 일정 갯수만큼 분류하고, 분류된 부분들 중 어떤 부분을 보내주는 것이 JPA Paging이다.

 

 

사용법

사용법은 매우 간단하다.
repository의 findAll 메서드의 parameter에 Pageable 또는 Pageable의 구현체인 PageRequest를 넣어주면 된다.
인터넷을 찾아보면 Controller에서 Pageable을 받아서 사용하는 코드들이 있는데 따라서 해보니 안된다.....
그래서 내가 이번에 구현한 PageRequest를 사용하는 방법만 소개한다.

 

 

PageRequest란

몇 페이지, 한 페이지의 사이즈, Sorting 방법(Option)을 가지고,
Repository에 Paging을 요청할 때 사용하는 것

 

 

 

PageRequest의 구조

위와 같이 인터페이스인 Pageable과 Serializable을 implements하는 AbstractPageRequest라는 추상 클래스가 있다.
그리고 PageRequest class는 이 AbstractPageRequest를 상속한다.

 

PageRequest의 생성자

PageRequest의 생성에는 찾을 page와 한 페이지의 size를 필수 인자로 받는다.
그리고 정렬해서 paging을 하는 경우에, Sort를 생성자 인자로 추가해서 PageRequest를 생성할 수 있다.
아래는 PageRequest class의 생성자 코드.
현재 다른 생성자들은 deprecated되고,
가장 아래 코드에서 보이는 정적 팩토리 메서드로 생성해야 한다. (of 메서드)

 

 

PageRequest의 사용

 

Repository에서 findAll 메서드를 살펴보면 위와 같이 Pageable을 인자로 줄 수 있다.
PageRequest는 Pageable 클래스를 implements한 AbstractPageReqeust 추상 클래스의 구현체이므로 findAll의 인자로 넣을 수 있다.

 

따라서 page,size,sort(option)으로 PageRequest를 생성하고,
Repository의 findAll 메서드의 인자에 PageRequest를 넣어주면 된다.
그러면 반환은 Page이 된다.

 

 

 

사용 예시

코드를 보면서 알아보자.
다른 복잡한 것들은 생략하고 설명에 필요한 구조는 다음과 같다.

 

몇 번째 페이지인지 의미하는 page와 한 페이지의 사이즈를 의미하는 size를 controller에 주고 해당 페이지의 Book들을 가져오는 API 구현하기
/paging URL에 RequestParam으로 page size가 주어짐

 

// BookController class
@GetMapping("/paging")
    public List<Book> findBooksByPageRequest(@RequestParam Integer page, Integer size) {
        return bookService.findBooksByPageRequest(page,size);
    }

 

 

BookController에서는 BookService에게 요청

 

// BookService class
public List<Book> findBooksByPageRequest(Integer page, Integer size) {
        PageRequest pageRequest = PageRequest.of(page,size);
        return bookRepository.findAll(pageRequest).getContent();
}

 BookService class에서는 주어진 page, size로 PageRequest를 생성한다.
(정적 팩토리 메서드를 사용해야 함)

 생성한 PageRequest을 BookRepository의 findAll 메서드 인자로 준다.

 반환은 List로 하기위해 getContent를 사용한다.
(getContent를 사용하지 않으면 Page이 findAll(pageRequest)의 반환 타입이다.

 

 

만약 Entity가 생성된 시간의 역순으로 Sorting해서 Paging하고 싶다면?

// BookService class
public List<Book> findBooksByPageRequest(Integer page, Integer size) {
        PageRequest pageRequest = PageRequest.of(page, size, Sort.by("createdAt").descending());
        return bookRepository.findAll(pageRequest).getContent();
}

 PageRequest의 마지막 인자로 Sort를 추가하면 된다.

 작성자는 Book을 추가한 날짜를 Book에 createdAt 이라고 했기 때문에 Sort.by의 인자에 "createdAt"을 넣었다.

 그리고 최신순으로 Paging해야 하므로 내림차순으로 정렬해야한다. 따라서 descending을 해줬다.

 

 

// BookController class
@GetMapping("/paging")
public Page<Book> findBooksByPageRequest(final Pageable pageable) {
      return bookService.findBooksByPageRequest(pageable);
}
// BookService class
public Page<Book> findBooksByPageRequest(Pageable pageable) {
   return bookRepository.findAll(pageable);
 }

 

'JPA' 카테고리의 다른 글

JPA - Jpa를 이용한 RESTful API 만들기  (0) 2022.09.08
JPA - Pageable  (0) 2022.09.02
JPQL - 벌크 연산  (0) 2022.07.10
JPQL - Named 쿼리  (0) 2022.07.10
JPQL - 엔티티 직접 사용  (0) 2022.07.10
복사했습니다!