Paging

leverest96·2023년 1월 13일
0

Spring / Java

목록 보기
11/20
post-thumbnail

Comment 구현을 하다가 이제 리스트를 불러와야해서 Repository에서 List<Comment>로 적다가 Page<Comment>로 바꾸라 해서 찾아보게 된 녀석...

개인적으로 List로 불러와서 page를 나누려고 했으나 JPA에는 그것마저 편하게 만드는 녀석이 있었다고 한다...


기본 개념

우선, JpaRepository의 부모 인터페이스 중 PagingAndSortingRepository가 있고 이 녀석이 페이징과 소팅이라는 기능을 제공한다.

findAll() 메서드의 반환 타입과 파라미터를 보면 다음과 같은 것들이 존재한다.

  1. org.springframework.data.domain.Pageable : 페이징을 제공하는 중요한 인터페이스
  2. org.springframework.data.domain.Page : 페이징의 findAll() 의 기본적인 반환 메서드로 여러 반환 타입 중 하나

결국 우리는 JpaRepository<> 를 사용할 때, 아래와 같이 findAll() 메서드를 Pageable 인터페이스로 파라미터를 넘기면 페이징을 사용할 수 있게된다.

final Pageable pageable = PageRequest.of(0, 5, Sort.by("createdDate").descending());

...

Page<Til> result = tilRepository.findAll(pageable);

이외에도 아래와 같이 findBy~~의 파라미터로 Pageable을 끼워 팔면 페이징을 사용할 수 있다.

public interface CommentRepository extends JpaRepository<Comment, Long> {
    Page<Comment> findByTilUuid(final String tilUuid, Pageable pageable);
}

파라미터 pageable에 들어갈 녀석을 만들어주기 위해서는 PageRequest라는 객체를 사용할 수 있다. (해당 객체는 Pageable 인터페이스를 상속받는다.)

  • PageRequest는 (페이지 수, 페이지 당 개수, Sorting, Sorting 기준)의 파라미터를 적용할 수 있다.

반환 타입

이 때, 반환 타입도 고려할 수 있는데 3가지 종류가 있다.

  1. Page<T> : 일반적인 게시판 형태의 페이징 (내가 사용할 녀석!)
  2. Slice<T> : 일정 수 이상일 경우 더보기 형태의 페이징
  3. List<T> : 그냥 리스트로 반환 (개인적으로 이건 그냥 paging과 무관한듯...?)

Controller

사실 Service단에서 처리는 간단했지만 Controller단에서 생각할 것이 하나가 생겨버렸다.

  1. Controller에서 파라미터로 Pageable이 아닌 Pageable의 파라미터를 받는다.
    @RequestParam final int page, @RequestParam final int size
  2. @PageableDefault로 Pageable을 받으면서 default 값을 설정해준다.
    @PageableDefault(page = 0, value = 5, sort = "createdDate", direction = Sort.Direction.DESC) final Pageable pageable
  3. 아무 것도 받지 않고 그냥 아래에서 생성해준다.
    final Pageable pageable = PageRequest.of(0, 5, Sort.by("createdDate").descending());

아무래도 확장성을 고려하자면 1번이었기 때문에! 나는 1번을 선택했다.


테스트 코드

  1. 페이징을 테스트하기 위해서는 Page<>의 결과물도 필요한데 그것은 아래처럼 PageImpl 인터페이스를 통해 구현할 수 있다.

    final List<Til> tils = List.of(TilFactory.createDefaultTil(profile));
    
    final Pageable pageable = PageRequest.of(0, 5, Sort.by("createdDate").descending());
    
    final Page<Til> tilPage = new PageImpl<>(tils, pageable, tils.size());
  2. 위에서 Pageable에 대한 파라미터를 Controller에서 받기로 했으니까 Controller test에서 ResultAction에서도 받아줘야한다.

    final ResultActions resultActions = mockMvc.perform(
            MockMvcRequestBuilders.get(url)
                    .param("page", "0")
                    .param("size", "5")
    );

https://wonit.tistory.com/483
https://www.baeldung.com/spring-data-web-support

profile
응애 난 애기 개발자

0개의 댓글