DB에 저장된 게시글을 조회할 때, 필드 값 기준에 따라 정렬을 구현하고자 한다.
현재 조회할 때 반환되는 게시글 response Dto 는 { title, contents, author, createdAt, modifiedAt } 필드 값을 가지고 있다.
클라이언트에서 정렬 기준이 될 필드 값과 정렬 방식(DESC, ASC)을 요청에 담아 보내면, 서버에서는 기준과 방식에 맞게 정렬된 데이터를 반환해야 한다.
두 가지 방식을 사용해서 정렬 기능을 구현할텐데,
첫번째는 Repository에 JPA Query method 기능을 사용하는 것이고,
두번째는 Pagination을 활용하는 것이다.
지금부터 하나씩 구현해보자!
@Repository
public interface BoardRepository extends JpaRepository<Board, Long> {
List<Board> findAllByOrderByModifiedAtDesc();
List<Board> findAllByOrderByTitleDesc();
List<Board> findAllByOrderByAuthorDesc();
}
findAllByOrderByModifiedAtDesc()
@GetMapping("/api/posts")
public List<BoardResponseDto> getPosts(@RequestParam(required = false, defaultValue = "modifiedAt", value = "orderby") String criteria) {
return boardService.getPosts(criteria);
}
required = false
: 해당 query param은 요청시 안 보낼 수도 있다.defaultValue = “modifiedAt”
: 안 보낸다면 디폴트 값은 “modifiedAt” 이다.value = "orderby"
: query 부분에서 Key 값은 “orderby” 다.public List<BoardResponseDto> getPostsOrderBy(String criteria) {
return switch (criteria) {
case "title" -> boardRepository.findAllByOrderByTitleDesc().stream().map(BoardResponseDto::new).toList();
case "author" -> boardRepository.findAllByOrderByAuthorDesc().stream().map(BoardResponseDto::new).toList();
default -> boardRepository.findAllByOrderByModifiedAtDesc().stream().map(BoardResponseDto::new).toList();
};
}
JPA 메서드를 Repository에서 선언만 해주면, 원하는 조건으로 정렬된 데이터를 얻을 수 있다.
하지만, 정렬 기준마다, 정렬 방식마다, 하나씩 모두 메서드를 선언해주어야 한다.
모든 정렬 기준을 생각하면 하나씩 만들기 번거로워서 우선 title, author 일 경우만 내림차순으로 생각하고 구현했다.
이제 조금 더 편하게 정렬된 데이터를 얻을 수 있는 Pagination 기능을 살펴보자!
PageRequest.of()
메서드로 생성이 가능하다.@GetMapping("/api/posts")
public Page<BoardResponseDto> getPostsPage(@RequestParam(required = false, defaultValue = "0", value = "page") int pageNo,
@RequestParam(required = false, defaultValue = "modifiedAt", value = "orderby") String criteria,
@RequestParam(required = false, defaultValue = "DESC", value = "sort") String sort) {
return boardService.getPostsPage(pageNo, criteria, sort);
}
public Page<BoardResponseDto> getPostsPage(int pageNo, String criteria, String sort) {
Pageable pageable = (sort.equals("ASC")) ?
PageRequest.of(pageNo, 5, Sort.by(Sort.Direction.ASC, criteria))
: PageRequest.of(pageNo, 5, Sort.by(Sort.Direction.DESC, criteria));
return boardRepository.findAll(pageable).map(BoardResponseDto::new);
}
PageRequest.of()
를 사용하여 pageable 객체를 생성해주고 findAll에 pageable을 넣으면, DB에서 찾은 값들이 설정했던 pagination 기능에 맞게 들어온다.@Repository
public interface BoardRepository extends JpaRepository<Board, Long> {
Page<Board> findAll(Pageable pageable);
}
page=1
: 1번 페이지(0번부터 시작한다.)orderby=author
: author 필드가 정렬 기준이다.sort=ASC
: 오름차순으로 정렬한다.