개발천재

[Spring Boot] 페이징 기능 구현하기 본문

개발 준비/Spring Boot

[Spring Boot] 페이징 기능 구현하기

세리블리 2025. 2. 26. 22:09
반응형

페이징 구현하기

스프링 부트에서 페이징(Paging)을 구현하는 방법은 Spring Data JPA의 Pageable과 Page<T> 인터페이스를 활용하는 것이다.

 

Page<T> 인터페이스를 사용하면 페이징 정보를 쉽게 가져올 수 있다. getTotalPages(), getTotalElements(), getNumber(), hasNext(), hasPrevious() 같은 유용한 메서드 제공하고 Pageable을 활용하여 PageRequest.of(page, size)로 요청이 가능하다.

Pageable을 사용하면 자동으로 페이징 쿼리를 실행한다. 정렬을 추가하려면 Sort 활용하고, 특정 조건으로 페이징하려면 findByXXX(String, Pageable) 사용한다. 컨트롤러에서 Page<Users>를 반환하면 JSON 타입으로 응답을 자동 처리할 수 있다.

 

Repository

Page<Users>를 반환하도록 설정하면 자동으로 페이징 처리가 된다.
Pageable을 파라미터로 받으면 Spring Data JPA가 자동으로 페이징 쿼리를 수행한다.

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UsersRepository extends JpaRepository<Users, Long> {
    Page<Users> findAll(Pageable pageable); // 페이징 지원하는 메서드
}

 

 

Service 계층
PageRequest.of(page, size)를 사용해 페이지 정보를 생성한다.
usersRepository.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 UsersService {
    private final UsersRepository usersRepository;

    public UsersService(UsersRepository usersRepository) {
        this.usersRepository = usersRepository;
    }

    public Page<Users> getUsersWithPaging(int page, int size) {
        Pageable pageable = PageRequest.of(page, size); // 페이지 번호와 크기 설정
        return usersRepository.findAll(pageable); // 페이징된 결과 반환
    }
}

 

 

Controller에서 사용

GET /users?page=0&size=10 요청을 하면 0번째 페이지, 10개 데이터를 가져온다.
Page<Users>를 반환하면 자동으로 JSON 응답으로 변환된다.

import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/users")
public class UsersController {
    private final UsersService usersService;

    public UsersController(UsersService usersService) {
        this.usersService = usersService;
    }

    @GetMapping
    public Page<Users> getUsers(@RequestParam(defaultValue = "0") int page,
                                @RequestParam(defaultValue = "10") int size) {
        return usersService.getUsersWithPaging(page, size);
    }
}

 

 


 

 

Sort 사용하여 정렬 추가하기

정렬을 추가하려면 PageRequest.of(page, size, Sort.by())를 사용한다.
Sort.by("createdAt").descending()을 사용해 최신순으로 정렬할 수 있다.

import org.springframework.data.domain.Sort;

public Page<Users> getUsersWithPagingAndSorting(int page, int size) {
    Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").descending()); 
    return usersRepository.findAll(pageable);
}

 

 

 

Query + Pageable 조합으로 특정 조건 페이징하기

특정 조건(예: "Red"를 좋아하는 사용자만 조회)에 따라 페이징을 적용할 수도 있다.

Repository 수정

Page<Users> findByFavoriteColor(String favoriteColor, Pageable pageable);

 


Service 수정

public Page<Users> getUsersByColor(String color, int page, int size) {
    Pageable pageable = PageRequest.of(page, size);
    return usersRepository.findByFavoriteColor(color, pageable);
}



Controller 수정

GET /users/color?color=Red&page=0&size=5 요청 시, "Red"를 좋아하는 사용자 5개씩 반환.

@GetMapping("/color")
public Page<Users> getUsersByColor(@RequestParam String color,
                                   @RequestParam(defaultValue = "0") int page,
                                   @RequestParam(defaultValue = "10") int size) {
    return usersService.getUsersByColor(color, page, size);
}

 

 


 

 

페이징 응답 JSON 예시

Page<Users> 객체를 JSON으로 변환하면 아래와 같은 형식으로 반환된다.

  • content: 실제 데이터 목록
  • totalPages: 전체 페이지 개수
  • totalElements: 전체 데이터 개수
  • size: 한 페이지에 들어가는 개수
  • number: 현재 페이지 번호
  • first, last: 첫 페이지인지, 마지막 페이지인지 여부
{
  "content": [
    { "id": 1, "name": "Alice", "email": "alice@example.com" },
    { "id": 2, "name": "Bob", "email": "bob@example.com" }
  ],
  "totalPages": 5,
  "totalElements": 50,
  "size": 10,
  "number": 0,
  "first": true,
  "last": false
}

 

 


 

 

Page<T>에서 제공하는 주요 페이징 메서드

메서드 설명
getTotalPages() 전체 페이지 수를 반환
getTotalElements() 전체 데이터 개수를 반환
getSize() 한 페이지당 표시할 데이터 개수 반환
getNumber() 현재 페이지 번호 반환 (0부터 시작)
getNumberOfElements() 현재 페이지에서 가져온 데이터 개수 반환
getContent() 현재 페이지의 데이터 리스트 반환 (List)
hasNext() 다음 페이지가 있는지 여부 반환 (boolean)
hasPrevious() 이전 페이지가 있는지 여부 반환 (boolean)
isFirst() 현재 페이지가 첫 번째 페이지인지 여부 반환
isLast() 현재 페이지가 마지막 페이지인지 여부 반환
nextPageable() 다음 페이지 정보를 담은 Pageable 객체 반환
previousPageable() 이전 페이지 정보를 담은 Pageable 객체 반환



Service (페이징 처리)

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class UserService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void printUserPages() {
        Pageable pageable = PageRequest.of(0, 5); // 첫 번째 페이지(0), 5개씩 가져오기
        Page<User> userPage = userRepository.findByFavoriteColor("Red", pageable);

        System.out.println("전체 페이지 수: " + userPage.getTotalPages());
        System.out.println("전체 데이터 개수: " + userPage.getTotalElements());
        System.out.println("현재 페이지 번호: " + userPage.getNumber());
        System.out.println("현재 페이지 데이터 개수: " + userPage.getNumberOfElements());
        System.out.println("첫 번째 페이지인가? " + userPage.isFirst());
        System.out.println("마지막 페이지인가? " + userPage.isLast());

        List<User> users = userPage.getContent();
        users.forEach(System.out::println);
    }
}



 
 
 
 

반응형