페이지네이션이란?
페이지네이션이란, 게시글이 많을 때 , 이를 전부 보여주지않고 페이지화 시켜서 보여주는것을 의미합니다.
보통 적은 규모의 데이터는 , 리소스를 서버에서 클라이언트로 전부 전달해도 성능에 큰 지장이없지만,
큰 규모의 데이터를 전달할 때(혹은 트래픽이 많은 서버), 쓸데 없이 모든 리소스를 전달하는 것보다.
해당 페이지의 리소스만 전달하는것이 서버 입장에 있어 부담이 덜 하기 때문에 사용합니다.
RESTFUL API로 설계된 서버에서, 페이지네이션을 구현하려면
두가지 단계가 필요합니다. 첫번째로, 총 페이지가 몇 페이지인지 클라이언트에게 전달해야합니다.
그래야만이 클라이언트는 이 리소스가 총 몇페이지가 있는지 확인 할 수 있습니다. 또한, 현재 페이지가 몇페이지인지 , 마지막페이지인지 첫번째페이지인지, 데이터의 수는 몇개인지, 정렬되었는지 등등의 추가 메타데이터를 함께 반환해야합니다.
두번째로, 해당 페이지에 있는 리소스를 반환 해야 합니다
이러한 과정을 편하게 추상화 시킨 Spring boot Page 라이브러리가 존재합니다.
Pageable 인터페이스
Pageable은 페이지 네이션의 메타데이터를 담고 있는 인터페이스로, 페이징 요청 시 필요한 페이지 번호, 페이지 크기, 정렬 방식 등을 캡슐화합니다. 이를 사용하여 데이터를 페이징 요청할 때 필요한 정보를 전달합니다.
주요 메서드:
- getPageNumber(): 요청한 페이지 번호를 반환합니다.
- getPageSize(): 한 페이지에 몇 개의 데이터를 요청하는지 반환합니다.
- getSort(): 정렬 정보를 반환합니다.
PageRequest
PageRequest는 Pageable의 구현체로, 실제 페이지네이션을 내가 어떻게 처리할건지 메타데이터를 정의함으로써 Pageable을 구현하게됩니다.
PageRequest.of() 메서드를 통해 PageRequest 구현체를 생성할 수 있습니다.
Pageable pageable = PageRequest.of(0, 10); // 0번 페이지, 페이지 크기 10
Pageable pageableWithSort = PageRequest.of(0, 10, Sort.by("createdAt").descending()); // 최신순으로 정렬
Page
Page는 페이지의 실제 데이터를 담고 있는 컨테이너 클래스입니다.
이 클래스는 데이터베이스에서 특정 페이지에 해당하는 데이터와 함께, 전체 데이터 개수, 페이지 수, 현재 페이지 정보등, PageRequest에서 정의했던 메타데이터를 함께 포함합니다. 그렇기 때문에. 클라이언트는 한번 반환된 Page객체를 보고, 총 리소스가 몇페이지인지, 현재 이페이지는 몇페이지인지, 이페이지의 데이터는 무엇인지를 확인 할 수 있습니다.
JPA를 이용해 Restful API에서 Pagenation 구현
수정하기 전 서비스 메서드
@Transactional(readOnly = true)
public List<Post> getPosts(Long userId){
return postRepository.findUserPosts(userId);
}
위 코드는, 매 요청마다 userId의 모든 Post를 반환하므로, 리소스를 과하게 사용하게됩니다.
이를 Pagenation을 구현하여 코드를 수정해보겠습니다.
JPA에서는 , pageable을 매개변수로받아 db에서 해당 페이지만 받아올 수 있도록 추상화하고있습니다.
JPA리포지토리에서, 아래와같이 매개변수로 peageable, 반환타입으로 Page를 선언해주면, 자동으로 추상화시켜주는 편한 기능을 제공하고있습니다.
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
Page<Post> findUserPosts(Long userId, Pageable pageable);
}
수정된 서비스 메서드
@Transactional(readOnly = true)
public Page<Post> getPosts(Long userId,int page){
Pageable pageable = PageRequest.of(page, 10, Sort.by("lastModifiedAt").descending());
Page<Post> pageResponse = postRepository.findUserPosts(userId,pageable);
return pageResponse;
}
PageRequest.of를 통해, 현재 페이지를 지정해주고, 페이지안의 총 리소스 수를 지정하고(10), 마지막으로는 해당페이지를 lastModifiedAt의 역순정렬로 최신 게시물이 가장 위로 향하게 합니다.
총 포스트가 1만개였다면, 수정하기 전에는 1만개의 리소스를 매번 반환하였지만,
수정한 후에는 일단 10개의 리소스만 찾게되므로, 서버의 부담이 줄어들어 성능이 향상되는 효과를 얻을 수 있습니다.
'Backend > Spring Boot' 카테고리의 다른 글
[Spring boot] Spring AOP - CGLIB Proxy vs Dynamic Proxy (0) | 2024.12.31 |
---|---|
[SpringBoot] QueryDsl의 Pagenation + PageableExecutionUtils을 이용해 count 쿼리 최적화 (1) | 2024.11.19 |
[Spring boot] JPA에서 Slice와 Page의 차이 (1) | 2024.10.07 |
[Spring Boot] Spring AI + Google vertex ai gemini 이미지 처리하기 (0) | 2024.06.27 |