반응형
오늘은 Spring Boot에서 Pagination(페이징)과 Sorting(정렬)을 구현하는 방법을 학습합니다. 대규모 데이터 처리 시 페이징과 정렬은 효율적인 데이터 조회를 위해 꼭 필요한 기능입니다.
1. Pagination과 Sorting의 필요성
- Pagination(페이징)
데이터를 페이지 단위로 나누어 클라이언트에 반환하여 서버 부하를 줄이고 사용자의 편의성을 제공합니다. - Sorting(정렬)
데이터를 특정 필드 기준으로 정렬하여 원하는 순서대로 결과를 반환합니다.
2. Spring Data JPA에서 제공하는 페이징과 정렬
Spring Data JPA는 Pageable과 Sort를 활용해 페이징과 정렬을 간단히 구현할 수 있습니다.
3. Pagination과 Sorting 설정하기
(1) 데이터베이스 엔터티 생성
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Double price;
// Getter, Setter
}
(2) 레포지토리 인터페이스 작성
Spring Data JPA의 JpaRepository를 상속받아 페이징과 정렬 기능을 제공합니다.
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ProductRepository extends JpaRepository<Product, Long> {
Page<Product> findByNameContaining(String name, Pageable pageable);
}
(3) 서비스 로직 작성
Pageable 객체를 사용하여 페이징과 정렬을 구현합니다.
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
@Service
public class ProductService {
private final ProductRepository productRepository;
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
public Page<Product> getProducts(String name, Pageable pageable) {
return productRepository.findByNameContaining(name, pageable);
}
}
(4) 컨트롤러 작성
클라이언트로부터 페이지 번호, 크기, 정렬 조건을 받아 데이터를 반환합니다.
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProductController {
private final ProductService productService;
public ProductController(ProductService productService) {
this.productService = productService;
}
@GetMapping("/products")
public Page<Product> getProducts(
@RequestParam(defaultValue = "") String name,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "id") String sortBy,
@RequestParam(defaultValue = "asc") String direction
) {
Sort sort = direction.equalsIgnoreCase("asc") ? Sort.by(sortBy).ascending() : Sort.by(sortBy).descending();
Pageable pageable = PageRequest.of(page, size, sort);
return productService.getProducts(name, pageable);
}
}
4. 페이징 응답 데이터 구조
Spring Data JPA는 Page 객체를 통해 아래와 같은 구조로 데이터를 반환합니다.
{
"content": [
{
"id": 1,
"name": "Product A",
"price": 100.0
},
{
"id": 2,
"name": "Product B",
"price": 200.0
}
],
"pageable": {
"sort": {
"sorted": true,
"unsorted": false,
"empty": false
},
"pageNumber": 0,
"pageSize": 10,
"offset": 0,
"paged": true,
"unpaged": false
},
"totalPages": 5,
"totalElements": 50,
"last": false,
"first": true,
"sort": {
"sorted": true,
"unsorted": false,
"empty": false
},
"size": 10,
"number": 0,
"numberOfElements": 10,
"empty": false
}
5. Postman으로 테스트
- 기본 요청: GET /products?page=0&size=5&sortBy=price&direction=asc
- 결과: 가격 순으로 오름차순 정렬된 데이터 반환.
- 검색 조건 추가: GET /products?name=Product&page=1&size=5&sortBy=name&direction=desc
- 결과: 이름에 "Product"가 포함된 데이터 반환.
6. 주요 사항 및 주의점
- 기본 정렬 설정
PageRequest.of에서 기본 정렬 설정을 잘못하면 예상치 못한 결과가 나올 수 있으니 유의합니다. - Pageable 객체 재사용
컨트롤러에서 Pageable 객체를 서비스로 넘길 때 매번 새로 생성해 성능에 유의합니다. - 무한 스크롤 대응
페이지 크기를 작게 설정하고 클라이언트에서 무한 스크롤 방식으로 데이터를 불러오도록 설계하면 사용자 경험이 향상됩니다.
반응형
'개발 > 전자정부프레임워크' 카테고리의 다른 글
Spring Security를 활용한 인증 및 권한 관리 기초 (0) | 2024.12.30 |
---|---|
RESTful API와 Spring Boot의 REST 컨트롤러 설계하기 (0) | 2024.12.30 |
Spring Boot에서 트랜잭션 관리(Transaction Management) 설정하기 (0) | 2024.12.29 |
Spring Boot에서 AOP(Aspect-Oriented Programming) 적용하기 (0) | 2024.12.29 |
Spring Boot에서 Security를 사용한 인증 및 권한 부여 (0) | 2024.12.29 |