ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring JPA Pageable 처리 - sort 및 Page 처리(totalElements)
    Spring/JPA 2024. 1. 9. 20:38

     

    Pageable

    Pagination 기능을 편리하게 사용할 수 있도록 JPA는 Pageable이라는 객체를 제공한다.

     

     

    controller 에서 부터 pageable 관련 파라미터를 받을 수 있다. 

    정렬 기능

    @GetMapping("/")
    public ResponseEntity getData(
                  @PageableDefault(size = 10, sort = "reqDt", direction= Sort.Direction.DESC)
                  Pageable pageable) 
    // reqDt 에 대한 내림차순 정렬


    @SortDefault 

    위의 방식은 정렬을 한가지만 할 수 있어, 여러 정렬 조건을 추가하려면 @SortDefault 를 추가하면 된다. 

    @GetMapping("/")
    public ResponseEntity getData(
          		@SortDefault.SortDefaults({
                  	@SortDefault(sort = "id", direction = Sort.Direction.ASC),
                    @SortDefault(sort = "reqDt", direction = Sort.Direction.DESC)
                  })
                  @PageableDefault(size = 10)
                  Pageable pageable) 
    // id 오름차순 및 reqDt 에 대한 내림차순 정렬

     

    controller 요청방법 

    ?page=0&size=10&sort=regDt,desc


    PageRequest

    다른 방법으로는 controller 에서 외에 paging 관련 데이터를 PageRequset 객체에 넣어 
    Pagable 을 생성 후 find 쿼리 메소드에 객체를 전달하면 된다.

     

    Pagable pageObj = PageRequest.of(0, 5, Sort.by("reqDt").descending().and(Sort.by("id")));

     

    controller 에서 부터 PageRequest 를 세팅 하고 싶다면 Pageable을 대체하는 PageRequest 관련 객체를 따로 생성하면 된다.

    public final class PageRequest {
    
        private int page;
        private int size;
        private Sort.Direction direction;
    
        public void setPage(int page) {
            this.page = page <= 0 ? 1 : page;
        }
    
        public void setSize(int size) {
            int DEFAULT_SIZE = 10;
            int MAX_SIZE = 50;
            this.size = size > MAX_SIZE ? DEFAULT_SIZE : size;
        }
    
        public void setDirection(Sort.Direction direction) {
            this.direction = direction;
        }
        // getter
    
        public org.springframework.data.domain.PageRequest of() {
            return org.springframework.data.domain.PageRequest.of(page -1, size, direction, "createdAt");
        }
     }
    • setPage(int page) 메서드를 통해서 0보다 작은 페이지를 요청했을 경우 1 페이지로 설정
    • setSize(int size) 메서드를 통해서 요청 사이즈 50 보다 크면 기본 사이즈인 10으로 바인딩
    • of() 메서드를 통해서 PageRequest 객체를 응답해줍니다. 페이지는 0부터 시작하니 page -1 합니다. 본 예제에서는 sort는 createdAt 기준으로 진행.

     


    Repository

    @Repository
    public interface BoardRepository extends JpaRepository<Board, Long> {
        Page<Board> findAll(Pageable pageable);
    }

    find 객체의 리턴에 Page<객체명> 을 해주면 자동으로 count 쿼리를 jpa 가 요청하여, paging 에 필요한 데이터를 조회 후 객체에 추가해 준다. 

    Pageable 에 해당 되는 size 및 page, sort 에 해당 되는 쿼리를 jpa 가 생성하여 보내준다.

     

    결과가 아래와 같이 생성된다.

    {
        "content": [
            {
                "id": 3,
                "name": "이름",
                "description": "설명",
                "createdAt": "2024-03-10T13:22:09",
                "updatedAt": "2024-03-10T13:22:09"
            },
            {
                "id": 2,
                "name": "이름2",
                "description": "자세한설명",
                "createdAt": "2024-03-10T13:22:09",
                "updatedAt": "2024-03-10T13:22:09"
            }
        ],
        "pageable": {
            "sort": {
                "empty": false,
                "sorted": true,
                "unsorted": false
            },
            "offset": 0,
            "pageSize": 2,
            "pageNumber": 0,
            "paged": true,
            "unpaged": false
        },
        "last": false,
        "totalPages": 3,
        "totalElements": 5,
        "size": 2,
        "number": 0,
        "sort": {
            "empty": false,
            "sorted": true,
            "unsorted": false
        },
        "first": true,
        "numberOfElements": 2,
        "empty": false
    }
     

     

     

    Page 객체는 totalPages 및 totalElements 값을 count 쿼리를 통해 가지고 있다.

    totalCount를 얻기 위해서는 다음과 같이 getTotalElements() 메서드를 사용한다:

    public interface Page<T> extends Slice<T> {
        static <T> Page<T> empty() {
            return empty(Pageable.unpaged());
        }
    
        static <T> Page<T> empty(Pageable pageable) {
            return new PageImpl(Collections.emptyList(), pageable, 0L);
        }
    
        int getTotalPages();
    
        long getTotalElements();
    
        <U> Page<U> map(Function<? super T, ? extends U> converter);
    }

     

     

    https://www.baeldung.com/spring-data-jpa-pagination-sorting [PageRequest 예시]

     
    반응형

    댓글

Designed by Tistory.