jpa

[JPA] Spring Data JPA의 Page객체에 대한 설명

우주유령 2025. 3. 26. 13:33
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();          // 마지막 페이지 여부

 

https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/Page.html

 

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
반응형