새소식

Spring

[Spring] Pageable과 PageRequest 개념과 비교

  • -

 

 

Pageable

 

1)    Pageable의 개념

 

Pageable은 데이터를 페이지 단위로 검색하고 제어하는 인터페이스

 

페이지 번호, 페이지 크기, 정렬 기준 설정을 통해 원하는 페이지의 데이터를 가져옵니다.

 

스프링 프레임워크에서 주로 사용되며, JPA와 함께 자주 활용됩니다.

 

 

 

2)    Pagealbe 인터페이스 메소드

 

● getPageNumber() : 현재 페이지 번호 가져오기

getPageSize() : 페이지 크기(한 페이지에 포함될 항목의 수) 가져오기 

● getOffset() : 페이지의 시작 항목 인덱스 가져오기

● getSort() : 정렬 기준 가져오기 (Sort 객체를 사용하여 속성과 정렬 방향을 지정할 수 있음)

● next() : 다음 페이지의 Pageable 생성

● previousOrFirst() : 이전 페이지의 Pageable 생성 (처음 페이지일 경우 첫번째 페이지의 Pageable 객체를 반환)

●  first() : 첫 번째 페이지의 Pageable 생성

●  hasNext() : 다음 페이지 여부 확인

●  hasPrevious() : 이전 페이지 여부 확인

 

 

 

3)    Pagealbe 유효성검사

 

페이지 번호와 페이지 크기의 유효성 검사는 페이지 요청이 유효한 범위 내에 있는지 확인하는 중요한 단계입니다.

 

① 페이지 번호 검사

Pageable 인터페이스의 getPageNumber() 메서드를 호출하여 페이지 번호를 가져온 후, 아래 두가지 조건을 확인합니다.

 

1) 페이지번호가 0부터 시작할 것 → 음수값이거나 0보다 작을 경우, 유효하지 않은 페이지 번호임

 

2) 페이지 번호는 전체 페이지 수보다 작아야 합니다.

 

 

② 페이지 크기 검사

Pageable 인터페이스의 getPageSize() 메서드를 호출하여 페이지 크기를 가져온 후, 아래 조건을 확인합니다.

 

페이지 크기는 1이상 일 것

→ 음수값이거나 0일 경우, 유효하지 않은 페이지 크기임

 

 

③ 예시

Pageable pageable = PageRequest.of(pageNumber, pageSize);

int pageNumber = pageable.getPageNumber();
int pageSize = pageable.getPageSize();

if (pageNumber < 0) {
    // 페이지 번호가 유효하지 않은 경우 처리
    throw new IllegalArgumentException("페이지 번호는 0 이상이어야 합니다.");
}

if (pageSize <= 0) {
    // 페이지 크기가 유효하지 않은 경우 처리
    throw new IllegalArgumentException("페이지 크기는 1 이상이어야 합니다.");
}

PageRequest를 사용하여 pageable 객체를 생성한 후,

getPageNumber() 메서드와 getPageSize() 메서드를 호출하여 페이지 번호와 페이지 크기를 가져옵니다.

 

이후, 각각의 값에 대해 유효성을 검사하고, 유효하지 않은 값이 감지되면 예외를 발생시킵니다.

 

 

 

 

4)    Pagealbe 정렬기준 설정시 주의점

 

Pageable에서 정렬 기준을 설정할 때 주의해야 할 몇 가지 사항이 있습니다.

 

 

① 정렬기준 유효성 검사

정렬 기준으로 사용할 필드는 엔티티에 실제로 존재해야 합니다.

→ 잘못된 필드 이름이나 존재하지 않는 필드를 사용하면 예외가 발생할 수 있습니다.

 

 

② 정렬방향 지정

정렬 방향은 오름차순(ASC) 또는 내림차순(DESC) 중에서 선택해야 합니다.

주로 Sort.Direction 열거형 상수인 ASC 또는 DESC를 사용하여 정렬 방향을 지정합니다.

정렬 방향을 올바르게 지정하지 않으면 기본적으로 오름차순으로 처리됩니다.

 

 

③ 정렬기준의 우선순위

Pageable에서는 여러 개의 정렬 기준을 지정할 수 있습니다. (정렬 기준 간의 우선순위가 중요)

 

정렬 기준을 지정하지 않으면 기본적으로 데이터베이스에서 제공하는 기본 정렬 순서에 따라 정렬됩니다.

(기본적으로 삽입한 순서 또는 기타 설정에 따라)

 

 

④ 정렬기준 조합

정렬 기준을 조합하여 복합 정렬을 수행할 수 있습니다.

예 → Sort.by("field1").and(Sort.by("field2"))와 같이 두 개의 정렬 기준을 조합하여 사용할 수 있습니다.

 

 

 

 

 

5)    Pagealbe 예시

 

UserRepository Interface

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.CrudRepository;

// ...

public interface UserRepository extends CrudRepository<User, Long> {
// UserRepository라는 인터페이스를 정의
// CrudRepository 인터페이스를 확장
// CrudRepository가 다룰 엔티티 클래스가 User, 그리고 그 식별자 타입이 Long임

    Page<User> findAll(Pageable pageable);
// UserRepository의 메소드 findAll을 선언
// 이 메서드는 Pageable 객체를 매개변수로 받고, User 엔티티의 Page를 반환합니다.
}

 

Myapp Class

@SpringBootApplication
public class MyApp implements CommandLineRunner {
// MyApp 클래스를 정의함

    @Autowired
    private UserRepository userRepository;
// UserRepository는 @Autowired 어노테이션을 사용하여 주입되어 
// User 엔티티에 대한 CRUD 작업을 수행

    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        int pageNumber = 0;
        int pageSize = 10;
        Sort sort = Sort.by(Sort.Direction.ASC, "username");

        Pageable pageable = PageRequest.of(pageNumber, pageSize, sort);
// PageRequest.of() 메서드를 사용하여 Pageable 객체를 생성하고
// 페이지 번호, 페이지 크기 및 정렬 정보를 지정

        Page<User> userPage = userRepository.findAll(pageable);
        List<User> userList = userPage.getContent();

        System.out.println("페이지 정보:");
        System.out.println("전체 페이지 수: " + userPage.getTotalPages());
        System.out.println("전체 항목 수: " + userPage.getTotalElements());
        System.out.println("현재 페이지 번호: " + userPage.getNumber());
        System.out.println("현재 페이지 크기: " + userPage.getSize());
        System.out.println("정렬 기준: " + userPage.getSort());
        System.out.println("페이지에 포함된 사용자 목록:");
        for (User user : userList) {
            System.out.println(user.getId() + ": " + user.getUsername());
        }
    }
}

 

 

출력값
페이지 정보:
전체 페이지 수: 3
전체 항목 수: 27
현재 페이지 번호: 0
현재 페이지 크기: 10
정렬 기준: username: ASC
페이지에 포함된 사용자 목록:
1: alice
2: bob
3: charlie
4: david
5: emma
6: frank
7: george
8: hannah
9: isaac
10: jack

 

 

 

 

 

PageRequest

 

1)    PageRequest의 개념

 

JPA에서 제공하는 구체적인 클래스로, 데이터를 페이지 단위로 검색하고 결과를 제어하는 데 사용되는 객체

 

페이지 번호, 페이지 크기, 정렬 기준을 지정할 수 있는 생성자를 제공

 

주로 JPA에서 사용됩니다.

 

 

 

2)    PageRequest 인터페이스 메소드

 

● getPageNumber() : 페이지 번호 가져오기

 

getPageSize() : 페이지 크기 가져오기

 

getOffset() : 페이지의 시작 항목 인덱스 가져오기

 

getSort() : 정렬 기준 가져오기 → Sort 객체를 사용하여 속성과 정렬 방향을 지정

 

next() : 다음 페이지의 PageRequest 생성

 

previousOrFirst(): 이전 페이지의 PageRequest 생성

 

first(): 첫 번째 페이지의 PageRequest 생성

 

hasNext(): 다음 페이지 여부 확인

 

hasPrevious(): 이전 페이지 여부 확인

 

 

 

 

3)    PageRequest 예시

 

UserRepository Class

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.CrudRepository;

// ...

public interface UserRepository extends CrudRepository<User, Long> {
    Page<User> findAll(PageRequest pageRequest);
}

 

 

Myapp Class

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;

@SpringBootApplication
public class MyApp implements CommandLineRunner {

    @Autowired
    private UserRepository userRepository;

    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        int pageNumber = 0;
        int pageSize = 10;
        Sort sort = Sort.by(Sort.Direction.ASC, "username");
        PageRequest pageRequest = PageRequest.of(pageNumber, pageSize, sort);

        Page<User> userPage = userRepository.findAll(pageRequest);
        List<User> userList = userPage.getContent();

        System.out.println("페이지 정보:");
        System.out.println("전체 페이지 수: " + userPage.getTotalPages());
        System.out.println("전체 항목 수: " + userPage.getTotalElements());
        System.out.println("현재 페이지 번호: " + userPage.getNumber());
        System.out.println("현재 페이지 크기: " + userPage.getSize());
        System.out.println("정렬 기준: " + userPage.getSort());
        System.out.println("페이지에 포함된 사용자 목록:");
        for (User user : userList) {
            System.out.println(user.getId() + ": " + user.getUsername());
        }
    }
}

 

 

출력값
페이지 정보:
전체 페이지 수: 3
전체 항목 수: 27
현재 페이지 번호: 0
현재 페이지 크기: 10
정렬 기준: username: ASC
페이지에 포함된 사용자 목록:
1: alice
2: bob
3: charlie
4: david
5: emma
6: frank
7: george
8: hannah
9: isaac
10: jack

 

 

 

 

 

 

차이점 비교

 

 

  PageRequest Pageable
인터페이스    PageRequest 클래스를 구체적인 구현체로 사용    Pageable 인터페이스를 구현한 다양한 구현체 사용 가능
주요 기능    페이지 번호, 페이지 크기, 정렬 기준 설정 가능    페이지 번호, 페이지 크기, 정렬 기준 설정 가능
생성자    PageRequest(int page, int size, Sort sort)    구현체에 따라 다양한 생성자 제공
상속 관계    PageRequest는 Pageable을 구현한 클래스    Pageable은 인터페이스로서 다양한 구현체로 확장 가능
정렬 기능    PageRequest에서 정렬 기준을 직접 설정    Pageable은 정렬 기준을 설정하는 메서드를 제공하는 인터페이스
사용 예시    Spring Data JPA의 페이징 및 정렬에 주로 사용    Spring MVC와 같은 스프링 프레임워크에서 페이지 요청에 사용
유효성 검사    페이지 번호와 페이지 크기의 유효성을 직접 검사해야 함    구현체에 따라 유효성 검사를 자동으로 수행하는 기능 가능

 

 

즉,

Pageable은 스프링 데이터에서 페이징 관련 기능을 추상화하고 표준화하기 위해 만들어진 인터페이스

 

PageRequest는 스프링 데이터 JPA에서 페이징된 결과를 생성하고 제어하기 위해 사용되는 구체적인 클래스

(PageRequest는 Pageable 인터페이스를 구현한 클래스로, Pageable의 구현체 중 하나입니다.)

 

 

모두 스프링 프레임워크에서 제공하는 기능으로 데이터베이스 조회 및 페이징 기능을 처리하는 데 사용됩니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2023.07.20 - [Spring] - [Spring] Spring Scheduler 이용하여 Slack 자동 알림 구현하기 (Slack 연동)

 

[Spring] Spring Scheduler 이용하여 Slack 자동 알림 구현하기 (Slack 연동)

SpringBoot + Slack 1. Slack Bot 생성하기 https://api.slack.com/ Slack은 생산성 플랫폼입니다 Slack은 팀과 커뮤니케이션할 수 있는 새로운 방법입니다. 이메일보다 빠르고, 더 조직적이며, 훨씬 안전합니다. sl

devwarriorjungi.tistory.com

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.