728x90
반응형
Spring Data JPA에서 Page<T> 객체는 페이징 처리된 결과를 담는 객체로, 조회된 데이터 리스트와 페이징 관련 정보를 함께 제공합니다.
1. Page 객체의 주요 기능
✅ 페이징된 데이터 목록 저장
- Page<T>는 조회된 엔티티 리스트를 가지고 있으며, 이를 List<T>처럼 사용할 수 있습니다.
✅ 전체 페이지 및 항목 개수 정보 제공
- 전체 데이터 개수
- 전체 페이지 수
- 현재 페이지 번호
- 페이지 크기
- 다음 페이지, 이전 페이지 여부
✅ 페이징 정보와 함께 결과 반환
- Page<T>는 단순 리스트가 아니라 총 개수와 페이지 정보까지 포함되어 있어, 페이징 UI 구현에 유용합니다.
2. Page 객체 사용법
📌 페이징 조회 메서드
Spring Data JPA의 JpaRepository를 사용하면, 간단하게 Page<T>를 반환하는 페이징 조회를 할 수 있습니다.
Page<User> findAll(Pageable pageable);
- Pageable을 파라미터로 받아서 페이징 처리된 Page 객체를 반환합니다.
📌 페이징 조회 예제
Pageable pageable = PageRequest.of(0, 10, Sort.by("id").descending());
Page<User> users = userRepository.findAll(pageable);
- PageRequest.of(0, 10, Sort.by("id").descending())
- 0번 페이지에서 10개 데이터 조회
- id 기준으로 내림차순 정렬
- users는 Page<User> 타입으로, 페이징된 데이터와 전체 개수 정보를 포함하고 있습니다.
3. Page 객체의 주요 메서드
int getTotalPages(); // 전체 페이지 수
long getTotalElements(); // 전체 데이터 개수
int getNumber(); // 현재 페이지 번호 (0부터 시작)
int getSize(); // 페이지 크기 (한 페이지에 포함된 데이터 개수)
int getNumberOfElements(); // 현재 페이지의 데이터 개수
boolean hasNext(); // 다음 페이지 존재 여부
boolean hasPrevious(); // 이전 페이지 존재 여부
List<T> getContent(); // 현재 페이지의 데이터 목록 반환
boolean isFirst(); // 첫 번째 페이지 여부
boolean isLast(); // 마지막 페이지 여부
Page (Spring Data Core 3.4.4 API)
getTotalPages int getTotalPages() Returns the number of total pages. Returns: the number of total pages
docs.spring.io
📌 예제: Page 객체 정보 출력
System.out.println("전체 페이지 수: " + users.getTotalPages());
System.out.println("전체 데이터 개수: " + users.getTotalElements());
System.out.println("현재 페이지 번호: " + users.getNumber());
System.out.println("페이지 크기: " + users.getSize());
System.out.println("현재 페이지 데이터 개수: " + users.getNumberOfElements());
System.out.println("다음 페이지 존재 여부: " + users.hasNext());
System.out.println("이전 페이지 존재 여부: " + users.hasPrevious());
List<User> content = users.getContent();
content.forEach(System.out::println);
4. Page vs Slice
Spring Data JPA에서 페이징을 처리할 때 Page와 Slice 두 가지를 사용할 수 있습니다.
PageSlice
전체 개수 조회 | count() 실행하여 전체 개수를 조회 | 전체 개수 조회하지 않음 |
다음 페이지 존재 여부 | 직접 hasNext() 호출 가능 | size + 1개의 데이터를 가져와서 판별 |
성능 | 개수 조회가 추가되므로 상대적으로 느림 | 개수 조회 없이 다음 페이지 판별하여 상대적으로 빠름 |
적용 예시 | 전체 개수를 알아야 하는 경우 | "더 보기" 방식으로 페이지네이션할 때 |
📌 사용 예제
Slice<User> findByName(String name, Pageable pageable);
- Slice는 전체 개수를 조회하지 않기 때문에 성능이 더 좋지만, 전체 페이지 수를 알 수 없음.
5. Page 객체를 DTO로 변환
Page 객체는 API 응답에 바로 반환하기보다는 DTO로 변환하여 필요한 정보만 전달하는 것이 일반적입니다.
📌 DTO 변환 예제
public class PageResponse<T> {
private List<T> content;
private int currentPage;
private int totalPages;
private long totalElements;
private boolean hasNext;
private boolean hasPrevious;
public PageResponse(Page<T> page) {
this.content = page.getContent();
this.currentPage = page.getNumber();
this.totalPages = page.getTotalPages();
this.totalElements = page.getTotalElements();
this.hasNext = page.hasNext();
this.hasPrevious = page.hasPrevious();
}
// Getter 생략
}
📌 사용 예시
Page<User> users = userRepository.findAll(pageable);
PageResponse<UserDto> response = new PageResponse<>(users.map(UserDto::fromEntity));
return ResponseEntity.ok(response);
- Page.map()을 활용하면 쉽게 DTO로 변환 가능!
6. 정리
✅ Page<T>는 페이징된 데이터를 포함하는 객체로, 전체 개수와 페이지 정보를 제공함
✅ Pageable을 사용하여 쉽게 페이징 처리 가능
✅ Page 객체의 다양한 메서드를 활용하여 UI에 필요한 페이징 정보를 제공
✅ 전체 개수를 조회할 필요가 없는 경우 Slice를 고려
✅ API 응답에서는 PageResponse DTO를 만들어 반환하는 것이 좋음
💡 결론:
Spring Data JPA의 Page 객체를 활용하면 페이징 처리를 쉽게 할 수 있으며, 성능과 API 응답 최적화를 위해 적절한 변환을 고려하는 것이 중요합니다! 🚀
728x90
반응형