- 일정을 Spring Data JPA의 Pageable과 Page 인터페이스를 활용하여 페이지네이션을 구현
- 페이지 번호와 페이지 크기를 쿼리 파라미터로 전달하여 요청하는 항목을 나타냅니다.
- 할일 제목, 할일 내용, 댓글 개수, 일정 작성일, 일정 수정일, 일정 작성 유저명 필드를 조회합니다.
- 디폴트 페이지 크기는 10으로 적용합니다.
- 일정의 수정일을 기준으로 내림차순 정렬합니다.
페이징 조회를하기위해 Spring Data JPA에서 제공하는 Pageble 인터페이스와 PageRequest 클래스를 사용하였습니다.
Pageble
Pageable은 데이터를 페이지 단위로 검색하고 제어하는 인터페이스입니다.
Pageable은 페이지 처리에 필요한 정보만 전달하는 용도이며, 실제 객체를 생성할 때는
PageRequest 클래스를 사용합니다.
PageRequest
이 클래스는 protected로 선언되어 있어서 new 생성자를 이용할 수 없어 생성하기 위해서는
of() 메서드를 이용하여 생성합니다.
PageRequest 클래스의 static 메서드는 다음과 같습니다.
of(int page, int size) : 0부터 시작하는 페이지 번호와 개수. 정렬이 지정되지 않음
of(int page, int size, Sort sort) : 페이지 번호와 개수, 정렬 관련 정보
of(int page int size, Sort sort, Direction direction, String ... props)
- 0부터 시작하는 페이지 번호와 개수, 정렬의 방향과 정렬 기준 필드들
public class PageRequest extends AbstractPageRequest {
private static final long serialVersionUID = -4541509938956089562L;
private final Sort sort;
protected PageRequest(int pageNumber, int pageSize, Sort sort) {
super(pageNumber, pageSize);
Assert.notNull(sort, "Sort must not be null");
this.sort = sort;
}
public static PageRequest of(int pageNumber, int pageSize) {
return of(pageNumber, pageSize, Sort.unsorted());
}
public static PageRequest of(int pageNumber, int pageSize, Sort sort) {
return new PageRequest(pageNumber, pageSize, sort);
}
public static PageRequest of(int pageNumber, int pageSize, Sort.Direction direction, String... properties) {
return of(pageNumber, pageSize, Sort.by(direction, properties));
}
public static PageRequest ofSize(int pageSize) {
return of(0, pageSize);
}
}
일정을 페이징 처리하여 조회하기 위해 TodoController와 Serivce, Repository의 코드를 수정하였습니다.
기존에는 그냥 findAll을 이용하여 모든 일정을 조회하였다면 이번엔 현재 페이지의 번호를 받아와서
of(int page int size, Sort sort, Direction direction, String ... props) 메서드를 이용하여
페이징 관련 정보들을 지정해준 뒤 파라미터로 같이 넘겨줍니다.
public class TodoController {
private final int pageSize = 10;
private final TodoService service;
@GetMapping
public ResponseEntity<List<TodoResponseDto>> todoFindAll(@RequestParam(defaultValue = "1", value = "nowPage")int nowPage){
Pageable pageable = PageRequest.of(nowPage-1, pageSize, Sort.Direction.DESC, "modifiedAt");
List<TodoResponseDto> todo = service.todoFindAll(pageable);
if(todo.isEmpty()) return new ResponseEntity<>(HttpStatus.NO_CONTENT);
return ResponseEntity.status(HttpStatus.OK).body(todo);
}
}
public List<TodoResponseDto> todoFindAll(Pageable pageable) {
// Repository에서 직접 쿼리문으로 limit / offset을 이용하여
// 페이징 처리된 데이터들을 뽑아오기 위하여
// pageable에서 각각의 값들을 받아온다.
int offsetNum = pageable.getPageNumber();
int limitNum = pageable.getPageSize();
offsetNum *= 10;
return todoRepository.findAll(limitNum,offsetNum).stream().map(TodoResponseDto :: new).toList();
}
public interface TodoRepository extends JpaRepository<Todo,Long> {
@Query("select t from Todo t order by t.modifiedAt desc limit :limitNum offset :offsetNum")
List <Todo> findAll(int limitNum, int offsetNum);
}
Postman을 이용한 테스트 결과
딱 10개만 받아오는 것을 볼 수 있다 !
[
{
"id": 20,
"title": "두두두두두가 글",
"content": "왕귀",
"createdAt": "2024-10-15T18:49:35.562998",
"modifiedAt": "2024-10-15T18:49:35.562998",
"commentsCount": 0,
"weather": "Foggy and Humid"
},
{
"id": 19,
"title": "두두두두두가 글",
"content": "왕귀",
"createdAt": "2024-10-15T18:49:34.879872",
"modifiedAt": "2024-10-15T18:49:34.879872",
"commentsCount": 0,
"weather": "Foggy and Humid"
},
{
"id": 18,
"title": "두두두두두가 글",
"content": "왕귀",
"createdAt": "2024-10-15T18:49:34.157666",
"modifiedAt": "2024-10-15T18:49:34.157666",
"commentsCount": 0,
"weather": "Foggy and Humid"
},
{
"id": 17,
"title": "두두두두두가 글",
"content": "왕귀",
"createdAt": "2024-10-15T18:49:33.458526",
"modifiedAt": "2024-10-15T18:49:33.458526",
"commentsCount": 0,
"weather": "Foggy and Humid"
},
{
"id": 16,
"title": "두두두두두가 글",
"content": "왕귀",
"createdAt": "2024-10-15T18:49:32.77839",
"modifiedAt": "2024-10-15T18:49:32.77839",
"commentsCount": 0,
"weather": "Foggy and Humid"
},
{
"id": 15,
"title": "두두두두두가 글",
"content": "왕귀",
"createdAt": "2024-10-15T18:49:31.747934",
"modifiedAt": "2024-10-15T18:49:31.747934",
"commentsCount": 0,
"weather": "Foggy and Humid"
},
{
"id": 14,
"title": "두두두두두가 글",
"content": "왕귀",
"createdAt": "2024-10-15T18:49:30.595366",
"modifiedAt": "2024-10-15T18:49:30.595366",
"commentsCount": 0,
"weather": "Foggy and Humid"
},
{
"id": 13,
"title": "두두두두두가 글",
"content": "왕귀",
"createdAt": "2024-10-15T18:49:29.90673",
"modifiedAt": "2024-10-15T18:49:29.90673",
"commentsCount": 0,
"weather": "Foggy and Humid"
},
{
"id": 12,
"title": "두두두두두가 글",
"content": "왕귀",
"createdAt": "2024-10-15T18:49:29.193057",
"modifiedAt": "2024-10-15T18:49:29.193057",
"commentsCount": 0,
"weather": "Foggy and Humid"
},
{
"id": 11,
"title": "두두두두두가 글",
"content": "왕귀",
"createdAt": "2024-10-15T18:49:28.495908",
"modifiedAt": "2024-10-15T18:49:28.495908",
"commentsCount": 0,
"weather": "Foggy and Humid"
}
]
이번에 Pageble 인터페이스와 PageRequest 클래스를 처음 사용해봤는데 페이징처리를 정말
손쉽게 할 수 있게해주는 착한 친구들인것같다
'TIL' 카테고리의 다른 글
JPA - JWT와 필터 구현하기 (1) | 2024.10.16 |
---|---|
영속성 컨텍스트 (1) | 2024.10.16 |
JPA - Entity (1) | 2024.10.15 |
JPA - 댓글 CRUD (2) | 2024.10.14 |
JPA - 일정 CRUD (1) | 2024.10.13 |