[문제]
마녀재판 프로젝트의 페이징 처리를 리팩토링해볼려고 합니다. 현재 페이징 처리는 다음과 같이 PagingDto를 상속받는 형식으로 정의가 되어 있습니다.
처음에는 Vue.js로 프론트로 구성할려고 생각하다 보니 Pageable을 파라미터로 받기 보다 PagingDto를 이용하여 page, size를 받을려고 했었는데, 중간에 타임리프를 사용하기로 결정하여 구성이 조금 꼬인 상황입니다.
현재 마녀재판의 페이징 처리에는 다음과 같은 문제가 있습니다.
- model로 페이징 처리에 필요한 많은 데이터를 넘겨주어야 한다.
- 페이징 처리를 위한 계산 로직과 검증 로직을 추가적으로 작성해주어야 한다.
객체를 이용하여 이를 한 줄로 바꿀 수 있지만, 이를 이미 제공하는 Pageable을 이용하여 리팩토링할려고 합니다.
[Pageable]
페이지네이션을 위한 인터페이스를 스프링 프레임워크에서 제공하고 있습니다. Pageable의 구현체인 PageRequest 클래스를 보면 page, size, sort에 대한 정보를 생성자를 통해 받고 있으며 현재 페이지, 사이즈 등을 알려주는 메소드도 구현이 되어 있습니다.
이렇게 Pageable 인터페이스와 그의 구현체가 제공하는 편리한 메소드들을 이용하여 리팩토링할려고 합니다.
[과정]
먼저 Request Dto의 PagingDto를 제거하고 Pageable을 이용하여 페이지 정보를 받을 수 있도록 수정하였습니다. Pageable을 사용할 경우 @PageableDefault 어노테이션을 이용하여 사이즈와 정렬 등에 대한 기본 정보를 설정할 수 있습니다.
그 다음은 조회 쿼리를 수정해주었습니다. queryDsl을 이용해서 쿼리를 작성하였으며 offset, limit에 pageable의 메소드를 호출하여 간단하게 페이징을 구현할 수 있습니다. PageImpl의 객체를 생성할 때 전체 카운트에 대한 정보가 필요하기 때문에 count쿼리도 따로 작성하였습니다.
수정한 queryDsl이 잘 동작하는지 단위 테스트를 돌려보고 성공하는지 확인합니다.
서비스와 컨트롤러도 같이 테스트 해주었습니다.
이전에 model로 값을 넘기던 일들을 boardList를 이용해 처리할 수 있도록 타임리프 수정 작업을 했습니다.
수정 완료된 컨트롤러 코드를 보면 페이징과 관련된 모든 정보가 boardList 객체에 담겨 있기 때문에, 모델로 넘겨주는 데이터가 최소환 된 것을 확인할 수 있습니다.
[정리]
이번에는 PagingDto를 이용한 페이징 처리 로직을 Pageable을 이용한 방법으로 로직을 변경하였습니다. PagingDto를 썼을 때는 필요한 정보만 모델에 담을 수 있다는 장점이 있었지만, 페이징을 위한 계산 로직과 그에 필요한 검증 로직을 직접 작성해야 한다는 점 그리고 페이징에 필요한 정보를 모델에 하나하나씩 담아서 넘겨주어야 한다는 단점이 있었습니다.
이를 해결하기 위해 Pageable 인터페이스를 활용하였습니다. 어노테이션을 활용해서 간단하게 기본 사이즈와 정렬 정보를 설정할 수 있고 페이징에 필요한 메소드와 검증 로직이 이미 작성되어 있는 장점이 있었습니다.