본문 바로가기
Back-End/Spring

TIL 230728 : pageable 기능 활용 하기. (+sortBy)

by 우인입니다 2023. 7. 28.

왜 쓰는걸까

기존에 repository에서 findAll 하면 죄다 가져왔다.

지금은 더미데이터 몇십개인데, 몇십만개가 된다면?

어차피 다 못 쓰는데 이는 낭비이다.

 

그래서 pageable을 이용해 원하는 만큼 데이터를 페이지 나눠주고 원하는 페이지를 가져오고 원하는 기준으로 정렬해서 가져다주는 기능을 제공하고 이를 통해 편하게 구현할 수 있다.

 

Pageable 쓰는 흐름

 

1. 페이지를 나누는 기준(필수), 정렬기준(옵션)을 정해서 pageable객체를 생성한다.

 

sort정보는 필수는 아닌것을 생성자 파라미터 정보로 알 수 있다.

 

 

 

2. pageable객체를 쿼리메소드에 넣어준다.

findAll() 파라미터를 보면 pageable을 받아서 처리해줄 수 준비가 되어있는 것을 확인할 수 있다.

 

 

 

3. Dto로 전달하기

보다시피 Page<T>형태로 받아왔다.

 

 

 

 

Pageable을 써서 얻을 수 있는 Response

{
    "content": [
        {"id": 1, "username": "User 0", "address": "Korea", "age": 0},
        ...
        {"id": 5, "username": "User 4", "address": "Korea", "age": 4}
    ],
    "pageable": {
        "sort": {
            "sorted": false, // 정렬 상태
            "unsorted": true,
            "empty": true
        },
        "pageSize": 5, // 페이지 크기
        "pageNumber": 0, // 페이지 번호 (0번 부터 시작)
        "offset": 0, // 해당 페이지의 첫번째 요소의 전체 순번 (다음 페이지에서는 5)
        "paged": true,
        "unpaged": false
    },
    "totalPages": 20, // 페이지로 제공되는 총 페이지 수
    "totalElements": 100, // 모든 페이지에 존재하는 총 원소 수
    "last": false,  // 마지막 페이지 여부
    "number": 0,
    "sort": {
        "sorted": false,    // 정렬 사용 여부
        "unsorted": true,
        "empty": true
    },
    "size": 5,       // Contents 사이즈
    "numberOfElements": 5,  // Contents 의 원소 수
    "first": true,   // 첫페이지 여부
    "empty": false   // 공백 여부
}

위처럼 페이징에 관련한 정보를 추가로 전달 받을 수 있다.

"contents"의 값으로 해당 객체들이 있고,

"pageable"의 값으로는 우리가 넣어줬던 pageable 정보가 담겨있고

그 아래에 결과적으로 페이징에 대한 정보들이 담겨있다.

 

마지막페이지인지 총 페이지 수는 어떻게 되는지, 총 갯수는 몇개인지 등.

 

+여기서 totalElements는 count쿼리를 발생시킨다.

전체 갯수를 세줘야하기 때문인데, 이 때문에 굳이 count 쿼리를 날릴 필요가 없는경우,

그저 List를 반환 받을 때에는 그냥 Page<T>대신 List<T>를 받아도 된다.

// 이부분은 List로 받아도됨 (userRepository 도 수정)
    Page<User> usersByUserRole = userRepository
            .findUsersByUserRole(UserRole.SELLER, pageDTO.toPageable());

//수정 후
    List<User> usersByUserRole = userRepository
            .findUsersByUserRole(UserRole.SELLER, pageDTO.toPageable());

 

 

+PageDto를 만들어서 pageable객체를 넣어줄 수 있다

public class PageDTO {
  @Positive // 0보다 큰수
  private Integer currentPage;
  private Integer size;
  private String sortBy;

  public Pageable toPageable() {
    return PageRequest.of(currentPage-1, size, Sort.by(sortBy).descending());
  }
}

 


 

더 배워야할 것

 

쿼리문 문법

쿼리문을 직접 짜보는 연습이 필요하다.

@Query 어노테이션을 사용해서 직접짜거나 하는 등 필수로 알아야하는 문법 같다.

 

 

무한스크롤

Slice<T>등을 써봐서 무한스크롤 연습?

 

 

실제 토이프로젝트에서 다시한번 연습해보며 구현해봐야할 것 같다.