게시판을 만들다보면 페이지를 나누어 글을 받아오고 표시하고 싶을 때가 있다
그럴때 페이징(Paging) 기능을 사용하면 된다
위 사진은 진행했던 토이프로젝트의 결과를 가져온 것이다
아래 코드 또한 해당 프로젝트의 일부이다
전체코드
https://github.com/seon7129/homeview
//PostingController에서
@GetMapping("/list/{categoryId}")
public Page<PostingResponseDTO> index(@PathVariable Long categoryId, @PageableDefault(sort = "postId",
direction = Sort.Direction.DESC) Pageable pageable) {
return postingService.list(categoryId, pageable);
}
컨트롤러에서는 @PageableDefault를 통해 페이징을 커스텀 할 수 있다
https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/web/PageableDefault.html
PostingResponseDTO는 원하는 데이터만 모아서 페이지 정보를 보내기 위해 만들었다
또한 카테고리별로 페이징을 하기 위해 카테고리를 주소에 입력받도록 하였다
//PostingService에서
...
public Page<PostingResponseDTO> list(Long categoryId, Pageable pageable) { // page로 반환
if (categoryId == 0) {
return allList(pageable);
}
Category category = makeNewCategory(categoryId);
List<Posting> postings = postingRepository.findByCategory(category);
Page<PostingResponseDTO> postingResponse = listtoPage(postingListtoPostingResponseList(postings), pageable);
return postingResponse;
}
...
private Page<PostingResponseDTO> listtoPage(List<PostingResponseDTO> postingResponse, Pageable pageable) {
int start = (int)pageable.getOffset();
int end = Math.min((start + pageable.getPageSize()), postingResponse.size());
Page<PostingResponseDTO> newPostings = new PageImpl<>(postingResponse.subList(start,end), pageable, postingResponse.size());
return newPostings;
}
...
위 컨트롤러에서 postingService.list에서 넘어와서 서비스단에서는 위와 같은 순서로 페이징이 진행되도록 하였다
만약 카테고리 번호가 0번이라면 카테고리 상관없이 모든 글들을 불러오도록 하였다
아니라면 카테고리 번호가 존재하는지 확인하고 JpaRepository를 이용하여 findByCategory로 포스팅 리스트를 받아온다
그리고 이를 페이지로 변환하는 과정을 진행했다
Repository 단계에서 바로 Page로 데이터를 받아오고 싶었는데 잘 동작하지 않아 리스트로 받고 페이지로 변환하는 방법을 사용했다..
{
"content": [
{
"postId": 17,
"member": {
"id": 5,
"name": "만보",
"nickname": "만보",
"email": "",
"password": "",
"role": "ROLE_MEMBER"
},
"category": {
"categoryId": 1,
"name": "자유"
},
"title": "하이를 수정ff",
"content": "하이 수정수정ff",
"postTime": "2023-07-04T03:18:44.034+00:00",
"postHits": 29,
"postLikes": 1
},
{
"postId": 16,
"member": {
"id": 2,
"name": "박재연",
"nickname": "t1t1",
"email": "",
"password": "",
"role": "ADMIN"
},
"category": {
"categoryId": 1,
"name": "자유"
},
"title": "안녕하세요",
"content": "안녕",
"postTime": "2023-07-04T03:17:52.913+00:00",
"postHits": 9,
"postLikes": 1
}
],
"pageable": {
"sort": {
"empty": false,
"sorted": true,
"unsorted": false
},
"offset": 0,
"pageNumber": 0,
"pageSize": 10,
"unpaged": false,
"paged": true
},
"last": true,
"totalPages": 1,
"totalElements": 2,
"first": true,
"size": 10,
"number": 0,
"sort": {
"empty": false,
"sorted": true,
"unsorted": false
},
"numberOfElements": 2,
"empty": false
}
포스트맨에서 테스트해보면 "주소/list/category=1"의 결과는 다음과 같다
페이징은 원하는 데이터만 정해진 갯수만큼 받아올 수 있어 효율적이고 데이터 뿐만 아니라 last(마지막 페이지인지), totalPages(총 페이지 수) 등을 이용할 수 있어서 게시판을 만드는데 굉장히 편리한 기능이다
https://yjkim-dev.tistory.com/48
https://wearegolden.tistory.com/entry/SPRINGJPA-PagingPagination-Pageable-%EA%B0%9D%EC%B2%B4-%EB%B0%9B%EC%95%84-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0