Backend/Spring

[Spring Boot] Pagination과 Sort

에반황 2019. 7. 11. 14:52

1. 개요

Pagination은 큰 데이터를 표현할 때 도움이 됩니다. 또한 어떠한 기준으로 데이터를 정렬하며 페이징해야할 수 있습니다.
이번 튜토리얼은 Spring Data Jpa를 사용하여 페이징하는 방법에 대해 알아보도록 하겠습니다.

 

 

2. 초기 셋업

첫 째로, Product 라는 entity를 다음과 같이 만들어봅시다:

@Entity
public class Product {

    @Id
    private long id;
    private String name;
    private double price; 

    // constructors, getters and setters 

}

우리의 도메인 클래스입니다. 각 Product 인스턴스는 유니크 식별자로 id를 사용하고 name과 price를 가지고 있습니다.

 

 

3. Repository 생성

우리가 만든 Product 에 접근하기 위해 ProductRepository 를 만들어봅시다.

public interface ProductRepository extends PagingAndSortingRepository<Product, Integer> {

    List<Product> findAllByPrice(double price, Pageable pageable);
}

PagingAndSortingRepository를 확장 함으로써, 페이징과 정렬을위한 findAll(Pageable Pageable)과 findAll (Sort sort) 메소드를 사용할 수 있습니다. 일단 PagingAndSortingRepository를 확장하면 위 코드의 findAllByPrice 처럼 Pageable, Sort 파라미터를 사용할 수 있게 됩니다. 또는, 우리는 PagingAndSortingRepository 를 확장한 JpaRepository 를 대신 사용하여도 됩니다.

 

 

4. Pagination

일단 우리의 repository를 PaginAndSortingRepository 를 통해 확장한 후에 다음을 하면 됩니다:

  1. Pageable 인터페이스를 구현한 PageRequest 객체를 만들거나 얻습니다.
  2. PageRequest 객체를 repository 메소드에 우리가 의도한데로 인자로 전달합니다.

PageRequest 객체는 요청된 페이지 숫자와 페이지 사이지를 넘김으로서 만듭니다. (페이지 숫자는 0부터 시작합니다):

Pageable firstPageWithTwoElements = PageRequest.of(0, 2);

Pageable secondPageWithFiveElements = PageRequest.of(1, 5);

Spring MVC에서는 Spring Data Web Support 를 이용해 Pageable 객체를 가져올 수도 있습니다.
PageRequest 객체가 있으면 repository 메소드를 호출하며 전달할 수 있습니다.

Page<Product> allProducts = productRepository.findAll(firstPageWithTwoElements);

List<Product> allTenDollarProducts = 
  productRepository.findAllByPrice(10, secondPageWithFiveElements);

findAll(Pageable pageable) 메소드는 기본적으로 Page 객체를 리턴합니다.
그러나, 우리는 또한 커스텀 메소드를 통해 페이지네이션된 데이터를 Page , Slice 또는 List 의 타입으로 받을 수 있습니다.

Page 인스턴스는 Product 의 목록 뿐 아니라 페이징할 수 있는 전체 목록의 숫자도 알고 있습니다. 이를 실행하기 위해 추가적으로 쿼리 작업이 들어갑니다. 이러한 작업에 대한 비용을 방지하기 위해, 우리는 대신 Slice나 List로 반환 받을 수 있습니다. Slice 는 단지 다음 slice가 가능한지 아닌지만 알고 있습니다.

 

 

5. Pagination과 Sorting

유사하게, 우리의 쿼리 결과를 정렬하기 위해선 Sort 객체를 메소드에 전달하면 됩니다.

Page<Product> allProductsSortedByName = productRepository.findAll(Sort.by("name"));

만약, 정렬과 페이지네이션을 둘다 하고 싶다면 어떻게해야할까요?

정렬에 대한 디테일 정보를 PageRequest 객체에 전달하면 됩니다.

Pageable sortedByName = 
  PageRequest.of(0, 3, Sort.by("name"));

Pageable sortedByPriceDesc = 
  PageRequest.of(0, 3, Sort.by("price").descending());

Pageable sortedByPriceDescNameAsc = 
  PageRequest.of(0, 5, Sort.by("price").descending().and(Sort.by("name")));

 

6. 결론

이번 튜토리얼에선, 어떻게 Spring Data JPA를 통해 쿼리된 데이터를 페이지네이트하고 정렬하는지 알아봤습니다.
이에 대한 튜토리얼은 Github 에서 찾아볼 수 있습니다.

반응형