왜 Pagination을 사용해야 할까?
데이터가 많아질수록 한 번에 모든 데이터를 불러오면 성능저하, 네트워크낭비, 응답 지연 문제가 생긴다.
그래서 일정 개수만 잘라서 가져오는 페이지네이션을 사용한다.
Spring Data JPA는 Pageable, Page 기능을 제공해주어 페이지네이션을 쉽게 구현할 수 있게 해준다.
Page<T>
- 실제 조회된 결과 + 페이지 정보
- 레포지토리에서 조회하면 페이지 객체 반환
Page<Schedule> pagination = scheduleRepository.findAll(pageable);
단순히 데이터 리스트가 아니라 페이지 정보를 함께 담고 있다.
Page 객체가 제공하는 정보
| 메서드 | 의미 |
| getContent() | 현재 페이지의 실제 데이터 List |
| getNumber() | 현재 페이지 번호 |
| getTotalPages() | 전체 페이지 수 |
| getTotalElements() | 전체 데이터 개수 |
| getSize() | 페이지 크기(size) |
| isFirst() | 첫 페이지 여부 |
| isLast() | 마지막 페이지 여부 |
| hasNext() | 다음 페이지 유무 |
| hasPrevious() | 이전 페이지 유무 |
Pageable
- 페이지 요청 정보를 담는 인터페이스
GET /schedules?page=1&size=10&sort=createdAt,desc
이 요청을 Spring MVC는 자동으로 Pageable로 변환해준다
적용해보기
1. Controller에서 Pageable 받기
스프링은 ?page=0&size=20 같은 쿼리 파라미터를 자동으로 Pageable로 변환해준다
@GetMapping
public ResponseEntity<PageScheduleResponse<GetAllScheduleResponse>> getAllSchedules(
Pageable pageable
) {
return ResponseEntity
.status(HttpStatus.OK)
.body(scheduleService.findAll(pageable));
}
이런 요청이 가능하다
GET /schedules?page=0&size=10
2. Service 에서 Page 객체 받기
Spring Data JPA로 페이지네이션은 한 줄로 가능하다
Page<Schedule> pagination = scheduleRepository.findAllByOrderByCreatedAtDesc(pageable);
3. 엔티티를 응답 DTO로 변환
페이지 내부 데이터는 엔티티이다. API 응답으로 반환하기 위해 DTO로 변환해서 사용해야 한다.
List<GetAllScheduleResponse> responses = pagination.getContent().stream()
.map(schedule -> new GetAllScheduleResponse(
schedule,
commentRepository.countAllByScheduleId(schedule.getId())
))
.toList();
- 각 일정의 개수(countAllByScheduleId)도 함께 내려주기 위해 추가 쿼리 수행
4. 커스텀 페이징 응답 만들기
페이지네이션에서 프론트엔드가 필요한 데이터가 있다. 나는 다음과 같은 정보만 커스텀 응답 DTO 필드로 넣어주었다.
- 데이터 목록
- 현재 페이지
- 전체 페이지
- 전체 데이터 수
- 첫 페이지 여부
- 마지막 페이지 여부
return new PageScheduleResponse<>(
responses,
pagination.getNumber(),
pagination.getTotalPages(),
pagination.getTotalElements(),
pagination.isFirst(),
pagination.isLast()
);
요약
- 클라이언트는 ?page=0&size=10 같이 요청
- Spring이 자동으로 Pageable로 변환
- Repository에서 findAll(Pageable) 또는 커스텀 메서드 호출
- 결과는 Page<T>로 반환
- Page의 content → DTO 변환
- 페이지 정보 + DTO 리스트를 묶어 커스텀 응답 생성
- Controller에서 응답
'Dev. > Spring' 카테고리의 다른 글
| [Spring] Lombok 생성자 @NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor (1) | 2025.11.20 |
|---|---|
| [Spring] 응답DTO에 엔티티 의존성을 주입해야 하는 경우 (0) | 2025.11.19 |
| [Spring] record DTO 클래스 (0) | 2025.11.17 |
| [Spring] DELETE 메소드에 RequestBody를 지양해야 하는 이유 (0) | 2025.11.13 |
| [Spring] Filter (0) | 2025.11.13 |