Paging & Pageable

dia·2024년 11월 29일

Paging

데이터를 여러 페이지로 나누어 필요한 데이터(페이지)만 로드하는 방식

Ideal Situation: 데이터가 많을 때
Efficiency: 메모리 절약, 성능 개선



Spring Data JPA에서의 Paging

Pageable (interface)

데이터베이스에서 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();
}

PageRequest (class)

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 객체에서 처리
    }
}

Page (interface)

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); // 페이징 처리된 데이터 반환
    }
}
profile
CS 메모장

0개의 댓글