페이징(Paging) : 사용자에게 데이터를 제공할 때, 전체 데이터 중의 일부를 보여주는 방식

→ 수많은 데이터들을 모두 화면에 뿌려준다면, 해당 데이터들을 가져오는 데에 많은 시간이 소요됨

관련 인터페이스 및 클래스

  1. Pageable 인터페이스 : 페이징 기능을 쉽게 구현할 수 있도록 제공하는 인터페이스

    → 페이지 번호(page), 크기(size), 정렬(sort) 정보를 담고 있어 이를 통해 필요한 부분의 데이터만 가져올 수 있음

    옵션 설명 비고
    page 현재 페이지 번호 지정 기본값 : 0 (0부터 시작)
    size 페이지 당 항목 수 지정 기본값 : 20 (설정에 따라 다를 수 있음)
    sort 데이터의 정렬 기준 설정 정렬 필드 지정
    정렬 방향 : asc / desc
  2. PageRequest 클래스 : Pageable의 구현체 중 하나로, 페이지 정보를 생성하는 클래스

    주요 메서드 설명
    of(int page, int size) 페이지 번호와 크기를 설정하여 PageRequest 객체 생성
    of(int page, int size, Sort sort) 페이지 번호, 크기, 정렬 기준 설정하여 PageRequest 객체 생성
    getPageNumber() 현재 페이지 번호 반환 (0부터 시작)
    getPageSize() 한 페이지 당 최대 항목 수 반환
    getOffset() 현재 페이지의 시작 위치 반환
    getSort() 정렬 정보 반환
    next() 다음 페이지의 Pageable 객체 반환
    previous() 이전 페이지의 Pageable 객체 반환
    previousOrFirst() 이전 페이지를 위한 Pageable 객체 반환
    이전 페이지가 없으면 첫 페이지 반환

    ⇒ 구체적인 페이징 처리와 정렬 기준을 설정하려면 PageRequest 클래스 사용

  3. Page<> : 페이징 된 결과를 반환하는 객체

    → 내부에 데이터 리스트와 페이징 메타데이터가 들어있음

    주요 메서드 설명
    List<T> getContent() 실제 데이터 리스트
    int getTotalPages() 전체 페이지 수
    long getTotalElements() 전체 데이터 수
    int getNumber() 현재 페이지 번호
    boolean hasNext() 다음 페이지 존재 여부
    boolean isFirst() 첫 페이지 여부

구현 방법

  1. Repository 계층 : Page<> 반환하도록 설정 + Pageable 파라미터로 설정

    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.jpa.repository.JpaRepository;
    
    public interface UserRepository extends JpaRepository<User, Long> {
        Page<User> findAll(Pageable pageable); // 페이징 지원하는 메서드
    }
    
  2. Service 계층 : PageRequest.of(page, size) 사용해 페이지 정보 생성

    → userRepository.findAll(pageable) 호출하면 자동으로 페이징 쿼리가 실행됨

    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.PageRequest;
    import org.springframework.data.domain.Pageable;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
        private final UserRepository userRepository;
    
        public Page<User> getUserWithPaging(int page, int size) {
            Pageable pageable = PageRequest.of(page, size); // 페이지 번호와 크기 설정
            return userRepository.findAll(pageable); // 페이징된 결과 반환
        }
    }
    
  3. Controller 계층 : request 파라미터로 page와 size 전달하여 사용

    import org.springframework.data.domain.Page;
    import org.springframework.web.bind.annotation.*;
    
    @RestController
    public class UsersController {
        private final UsersService usersService;
    
        @GetMapping("/user") // /users?page=0&size=10 요청
        public Page<Users> getUsers(@RequestParam(defaultValue = "0") int page,
    	                                @RequestParam(defaultValue = "10") int size) {
            return usersService.getUsersWithPaging(page, size);
        }
    }