본문 바로가기
코딩 공부/web & Java

[Spring] Pageable

by 현장 2025. 4. 8.

Pageable

Pageable은 Spring Framework (특히 Spring Data)에서 페이징 처리를 쉽게 하기 위해 제공하는 인터페이스입니다. 즉,  "어떤 페이지를, 몇 개씩 가져올지 알려주는 정보"라고 이해하면 됩니다.

 

이러한 페이징을 개발하기 위해서는 page 관련 쿼리를 파라미터로 받아서 직접 처리하는 방법이 있었지만 Spring 프로젝트에서는 효과적으로 페이징을 처리할 수 있게 방법이 있습니다.

🏷️ 의존성

// jpa를 사용 안하는 경우
implementation 'org.springframework.data:spring-data-commons'

// jpa를 사용하는 경우
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

위에 의존성을 사용하면 JPA는 사용하지 않지만, Pageable, Page, Slice 등 페이징 관련 유틸 클래스를 사용하고 싶은 경우에도 사용이 가능합니다.

🏷️ 주요 구성 요소

구성 예시 설명
page 0 몇 번째 페이지 (0부터 시작)
size 10 한 페이지에 몇 개 항목
sort createdAt,desc 어떤 컬럼 기준으로 정렬할지

🏷️ 사용 방법 예시

✅ Repository

public interface UserRepository extends JpaRepository<User, Long> {
    Page<User> findAll(Pageable pageable);
}

✅ Controller

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    // 방법 1: RequestParam으로 page/size 직접 받기
    // → 정렬 옵션 등을 코드로 제어할 때 유리
    @GetMapping("/page1")
    public ResponseEntity<Page<User>> page(
            @RequestParam int page,
            @RequestParam int size) {

        Pageable pageable = PageRequest.of(page, size);
        Page<User> users = userRepository.findAll(pageable);
        return ResponseEntity.ok(users);
    }

    // 방법 2: Pageable을 메서드 인자로 자동 주입
    // → page, size, sort 등을 클라이언트에서 직접 조절 가능
    @GetMapping("/page2")
    public Page<User> getUsers(Pageable pageable) {
        return userRepository.findAll(pageable);
    }
}

이러면 GET방식으로  /members?page=0&size=3과 같은 API를 호출하면 Spring이 알아서 Pageable 객체에 매핑해 줍니다. 또한 GET방식으로 /members처럼 쿼리 파라미터를 따로 지정하지 않아도, JPA 자체 default 값인 (page=0&size=20)에 따라 페이징을 처리합니다.

✔️ defulat 값 변경하는 법

1. application.yml으로 글로벌 설정 변경

spring.data.web.pageable.default-page-size=20

 

2. @PageableDefault을 통한 개별 설정 변경

@GetMapping
public Page<User> getUsers(
	@PageableDefault(
        size = 10, // 한 page 사이즈
        sort = "createdAt", // 정렬 기준
        direction = Sort.Direction.DESC // 정렬 차순(오름차순, 내림차순)
    ) Pageable pageable
) {
    return userRepository.findAll(pageable);
}

✅ 결과 예시

// json
{
  "content": [ ...유저 데이터... ],
  "totalPages": 10,
  "totalElements": 100,
  "size": 10,
  "number": 1,
  "first": false,
  "last": false
}

🏷️ 반환 타입

✅ Page

@GetMapping
public Page<User> getUsers(Pageable pageable) {
    return userRepository.findAll(pageable);
}

가장 많이 사용되는 반환 타입으로 전체 데이터 개수, 총 페이지 수, 현재 페이지 등의 페이징 정보와 데이터 리스트를 함께 담고 있습니다.

 

다음과 같은 경우 사용을 고려해볼 수 있습니다.

 

  • 전체 개수(total count)가 필요한 경우
  • 클라이언트에서 페이지네이션 UI 구성할 때 유용

 

Slice

Page보다 가벼운 구조로 전체 개수(totalElements)는 없고 다음 페이지가 있는지만 알려줍니다.(hasNext)

@GetMapping("/slice")
public Slice<User> getUserSlice(Pageable pageable) {
    return userRepository.findAll(pageable);
}

다음과 같은 경우 사용을 고려해볼 수 있습니다.

 

  • 성능이 중요한 모바일 앱, 무한 스크롤 UI 등
  • 전체 개수는 굳이 필요 없고, "다음 페이지가 있냐?"만 필요한 경우

✅ List

페이징 정보를 무시하고 데이터만 받고 싶을 때 사용합니다.

@GetMapping("/list")
public List<User> getUserList() {
    return userRepository.findAll(); // 모든 데이터 가져옴
}

// 또는 아래처럼 Pageable을 써도 그냥 리스트만 받는 경우
@GetMapping("/paged-list")
public List<User> getUserList(Pageable pageable) {
    return userRepository.findAll(pageable).getContent(); // 리스트만 꺼냄
}

 

다음과 같은 경우 사용을 고려해볼 수 있습니다.

 

  • 페이징 정보 필요 없고, 리스트만 보내줄 때
  • 혹은 프론트에서 페이징 따로 처리할 때

📖 Reference

danurig

 

'코딩 공부 > web & Java' 카테고리의 다른 글

[Spring] BCryptPasswordEncoder  (0) 2025.04.04
[Java] Comparable과 Comparator  (0) 2025.04.04
[Java] Stream  (0) 2025.04.02
[JPA] CRUDRepository와 JPARepository  (0) 2025.04.01
[Mockito] ArgumentMatchers 및 any,eq  (1) 2024.10.21