이번에는 페이징을 구현해 볼 것이다.
순수 JPA를 이용해서...
// PostRepository.java
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
Page<Post> findAllByOrderByIdDesc(Pageable pageable);
}
페이징을 이용하기 위해서는 Pageable 인터페이스를 이용하도록 한다.
해당 인터페이스를 이용하면 페이지 번호, 페이지 크기, 정렬 순서 정볼르 이용하여 Paging을 쿼리 없이 사용할 수 있다!
주요 메소드로는
이 있다.
자세한 것은 docs로
레포지토리를 위와 같이 작성하면 모든 데이터를 ID를 기준으로 내림차순 한 후, 페이징을 이용하여 값을 가져오게 된다.
기존에 사용하는 Response DTO에는 전체 페이지 수를 반환하지 않는다.
따라서 전체 페이지 수를 같이 반환할 수 있도록 아래와 같이 수정하자.
// PostResponse.java
@Getter
@Setter
@AllArgsConstructor
public class PostResponse {
public Integer counts;
public List<ResponseData> data;
public PostResponse() {
data = new ArrayList<>();
}
public PostResponse(Integer counts) {
this.counts = counts;
data = new ArrayList<>();
}
@AllArgsConstructor
public static class ResponseData {
public Long id;
public String title;
public String content;
}
}
빈 생성자로는 ArrayList만 생성하고, counts가 있는 생성자로는 counts를 초기화 및 ArrayList를 생성한다.
내부에 ResponseData 클래스를 하나 생성하고, 해당 클래스를 데이터로 갖는 List를 생성한다.
Pageable을 사용하기 위해 Pageable 변수를 초기화하는 과정을 가진다.
public PostResponse getPage(Integer pageNo) {
Pageable pageable = PageRequest.of(pageNo, 10);
Page<Post> page = postRepository.findAllByOrderByIdDesc(pageable);
PostResponse res = new PostResponse(page.getTotalPages());
page.getContent().forEach( post -> res.data.add(new PostResponse.ResponseData(post.getId(), post.getTitle(), post.getContent())));
return res;
}
Pageable pageable = PageRequest.of(pageNo, 10);
Pageable 클래스를 초기화하는 과정.
페이지 번호와 몇 개씩 조회할 것인지를 설정한다.
page.getContent().forEach( post -> res.data.add(new PostResponse.ResponseData(...)));
페이징한 결과를 Response에 맞게 수정한다.
// PostController.java
@GetMapping("")
public ResponseEntity<PostResponse> getPosts(@RequestParam("pages") Integer pageNo) {
PostResponse page = postService.getPage(pageNo);
return ResponseEntity.status(HttpStatus.OK).body(page);
}
이로서 얻은 페이징 결과값을 반환을 한다.
/posts?pages=0
결과를 한번 보자.
{
"counts": 2,
"data": [{
"id": 157,
"title": "asdf11",
"content": "qwer11"
}, {
"id": 156,
"title": "asdf10",
"content": "qwer10"
}, {
"id": 155,
"title": "asdf9",
"content": "qwer9"
}, {
"id": 154,
"title": "asdf8",
"content": "qwer8"
}, {
"id": 153,
"title": "asdf7",
"content": "qwer7"
}, {
"id": 152,
"title": "asdf6",
"content": "qwer6"
}, {
"id": 103,
"title": "asdf5",
"content": "qwer5"
}, {
"id": 102,
"title": "asdf4",
"content": "qwer4"
}, {
"id": 53,
"title": "asdf3",
"content": "qwer3"
}, {
"id": 52,
"title": "asdf2",
"content": "qwer2"
}
]
}
정상적으로 반환됨을 볼 수 있다!
pages=3
인 경우, {"counts":2,"data":[]}
결과가 나온다.
PostResponse DTO를 수정하였으니, UserController의 getUserWritingDetail를 수정하자.
// UserController.java
private List<PostResponse.ResponseData> getUserWritingDetail(List<Post> p) {
List<PostResponse.ResponseData> res = new ArrayList<>();
p.forEach(a -> res.add(new PostResponse.ResponseData(a.getId(), a.getTitle(), a.getContent())));
return res;
}
이로서 페이징을 완료하였다.
만세!