데이터를 여러 페이지로 나누어 필요한 데이터(페이지)만 로드하는 방식
Ideal Situation: 데이터가 많을 때
Efficiency: 메모리 절약, 성능 개선
Spring Data JPA에서의 Paging
데이터베이스에서 Paging을 구현할 때 사용되는 인터페이스
package org.springframework.data.domain;
public interface Pageable {
// 현재 페이지 번호 반환 (페이지 번호는 0부터 시작)
int getPageNumber();
// 한 페이지의 크기 (= 한 번에 가져올 데이터 수) 반환
int getPageSize();
// 페이지의 시작 위치(offset) 반환 (= pageNumber * pageSize)
long getOffset();
// 데이터를 정렬할 때 사용할 정렬 기준(Sort) 반환
Sort getSort();
// 페이지가 첫 번째 페이지인지 확인하는 메서드
default boolean isFirst() {
return getPageNumber() == 0;
}
// 페이지가 마지막 페이지인지 확인하는 메서드
default boolean isLast() {
return !hasNext();
}
// 다음 페이지가 있는지 확인하는 메서드
default boolean hasNext() {
return getPageNumber() + 1 < getTotalPages();
}
// 전체 페이지 수를 계산하여 반환하는 메서드 (일반적으로 페이지 계산은 Page 객체에서 처리)
int getTotalPages();
}
Pageable 인터페이스를 구현한 대표적인 클래스
package org.springframework.data.domain;
public class PageRequest implements Pageable {
private final int pageNumber;
private final int pageSize;
private final Sort sort;
public static PageRequest of(int page, int size) {
return new PageRequest(page, size, Sort.unsorted());
}
public static PageRequest of(int page, int size, Sort sort) {
return new PageRequest(page, size, sort);
}
private PageRequest(int pageNumber, int pageSize, Sort sort) {
this.pageNumber = pageNumber;
this.pageSize = pageSize;
this.sort = sort != null ? sort : Sort.unsorted();
}
@Override
public int getPageNumber() {
return this.pageNumber;
}
@Override
public int getPageSize() {
return this.pageSize;
}
@Override
public long getOffset() {
return (long) this.pageNumber * (long) this.pageSize;
}
@Override
public Sort getSort() {
return this.sort;
}
@Override
public int getTotalPages() {
return 0; // 페이지 수는 Page 객체에서 처리
}
}
package org.springframework.data.domain;
import java.util.List;
public interface Page<T> extends Slice<T> {
// 페이지에 포함된 데이터 목록 반환
List<T> getContent();
// 전체 페이지 수 반환
int getTotalPages();
// 전체 데이터 개수 반환
long getTotalElements();
// 현재 페이지 번호 반환
int getNumber();
// 페이지 크기 (한 페이지에 포함된 데이터 수) 반환
int getSize();
// 현재 페이지에 데이터가 더 있는지 여부 반환
boolean hasNext();
// 마지막 페이지인지 여부 반환
boolean isLast();
// 첫 번째 페이지인지 여부 반환
boolean isFirst();
// 페이지에 데이터가 없는지 여부 반환
boolean hasContent();
}
@RestController
public class ExampleController {
@Autowired
private ItemRepository itemRepository;
@GetMapping("/items")
public Page<Item> getItems(@RequestParam int page, @RequestParam int size) {
Pageable pageable = PageRequest.of(page, size); // 페이지 번호와 크기 지정
return myRepository.findAll(pageable); // 페이징 처리된 데이터 반환
}
}