오늘은 @PageableDefault
를 사용하여 간단하게 페이징 처리하는 방법에 대해 알아보려고 합니다.
@PageableDefault
는 Spring Data Web에서 지원하는 어노테이션으로, 스프링 MVC에서 페이지네이션을 쉽게 구현할 수 있도록 도와줍니다.
@PageableDefault
를 사용하여 컨트롤러의 메서드 파라미터에서 기본 페이지 사이즈, 정렬 순서, 페이지 번호 등을 설정할 수 있습니다.
@PageableDefault
는 Pageable
객체를 메서드 파라미터로 받을 때 사용됩니다. @Pageable
은 Spring Data 라이브러리에서 페이지네이션과 정렬 기능을 추상화한 인터페이스이며 요청된 페이지 번호, 페이지 크기, 정렬 순서와 같은 페이징 처리에 필요한 정보를 캡슐화한 객체입니다. Spring Data JPA 등 다양한 스프링 데이터 모듈에서 페이지네이션 처리하는데 사용됩니다.
@PageableDefault
어노테이션의 속성을 지정하여 페이지네이션 기본 속성값을 세팅할 수 있습니다.
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface PageableDefault {
/**
* Alias for {@link #size()}. Prefer to use the {@link #size()} method as it makes the annotation declaration more
* expressive and you'll probably want to configure the {@link #page()} anyway.
*
* @return
*/
@AliasFor("size")
int value() default 10;
/**
* The default-size the injected {@link org.springframework.data.domain.Pageable} should get if no corresponding
* parameter defined in request (default is {@code 10}).
*/
@AliasFor("value")
int size() default 10;
/**
* The default page number the injected {@link org.springframework.data.domain.Pageable} should use if no
* corresponding parameter defined in request (default is {@code 0}).
*/
int page() default 0;
/**
* The properties to sort by default. If unset, no sorting will be applied at all.
*
* @return
*/
String[] sort() default {};
/**
* The direction to sort by. Defaults to {@link Direction#ASC}.
*
* @return
*/
Direction direction() default Direction.ASC;
}
보통 클라이언트에서 페이지네이션에 대한 요청을 보낼 때 /reports?page=2&size=5
와 같이 요청을 합니다.
이 경우 URL의 파라미터가 @PageableDefault
에 의해 정의된 기본값보다 우선시 하게 됩니다.
즉, page=?&size=?
쿼리파라미터가 존재할 시 Pageable 객체에 해당 page, size에 대한 정보가 들어가게 되고 없을 시엔 @PageableDefault
에 설정된 기본 정보가 Pageable 객체에 들어가게 되는 것입니다.
@RestController
@RequiredArgsConstructor
public class ReportController {
private final ReportRepository reportRepository;
@GetMapping("/reports")
public Page<ReportResponseDto> getReportList(ReportSearchCondition condition, @PageableDefault(size = 10, sort = "jobPost", direction = org.springframework.data.domain.Sort.Direction.ASC Pageable pageable) {
return reportRepository.getReportList(condition, pageable);
}
}
public interface ReportRepository extends JpaRepository<Report, Long> {
@Query("SELECT new com.yourdomain.ReportResponseDto(r) FROM Report r WHERE (:#{#condition.name} IS NULL OR r.name = :#{#condition.name}) AND (:#{#condition.status} IS NULL OR r.status = :#{#condition.status})")
Page<ReportResponseDto> getReportList(@Param("condition") ReportSearchCondition condition, Pageable pageable);
}
Spring Data JPA의 JpaRepository 인터페이스를 상속받은 Repository에서 페이지네이션을 처리하는 방법은 위의 코드와 같이 간단합니다.
@Query
에 설정된 쿼리를 실행하여 조회한 값에 대해 Pageable
객체의 정보를 이용하여 해당 결과를 자동으로 페이지네이션 해주기 때문에 파라미터에 Pageable
객체만 넣어주면 끝입니다.
반환 타입은 Page 인터페이스이며 해당 인터페이스의 기본 구현체인 PageImpl을 반환하게 됩니다. 해당 객체에서 content, totalPage, isLast, hasNext 등 페이지네이션 결과에 대한 정보들을 조회할 수 있습니다.