-
QueryDSL 페이징에 QuerydslPredicateExecutor 활용하기JPA 2023. 10. 3. 00:01
QuerydslPredicateExecutor란?
Predicate 인스턴스를 실행할 수 있도록 spring data에서 지원하는 인터페이스입니다.
반환값들을 보면 Page<T>로 Predicate를 통해 페이징 된 결과를 받을 수 있습니다.
인터페이스의 네이밍을 보았을 때 Predicate를 기반으로 실행한다!라고 이해할 수 있습니다.
Predicate란?
Predicate를 직역하면 서술어라는 의미를 가집니다.
간단하게는 where 절에 들어가는 조건문을 뜻합니다.
BooleanBuilder, BooleanExpression이 Predicate 인터페이스를 구현하고 있습니다.
사용법
QuerydslPredicateExecutor 인터페이스 상속받기
@Repository interface DeliveryJpaRepository : JpaRepository<DeliveryJpaEntity, UUID>, CustomDeliveryJpaRepository, QuerydslPredicateExecutor<DeliveryJpaEntity> { }
Adapter 부분 구현
fun loadNeedToReadyDeliveries(page: Int, size: Int, productId: Long?): Page<Delivery> { val booleanExpression = generateLoadNeedToReadyDeliveriesPredicate(productId) val pageable = PageRequest.of(page - 1, size, Sort.by("expectedDeliveryAt")) return deliveryJpaRepository.findAll(booleanExpression, pageable) .map { it.toDomainEntity() } } private fun generateLoadNeedToReadyDeliveriesPredicate(productId: Long?): Predicate { val qDelivery: QDeliveryJpaEntity = QDeliveryJpaEntity.deliveryJpaEntity return qDelivery.deliveryStatus .eq(DeliveryStatus.WAITING) .and(qDelivery.expectedDeliveryAt.isNotNull) .and(productId(productId)) } private fun productId(productId: Long?): BooleanExpression?{ val qDelivery: QDeliveryJpaEntity = QDeliveryJpaEntity.deliveryJpaEntity if(productId == null){ return null } return qDelivery.productId.eq(productId) }
booleanExpression을 활용하여 쿼리를 구성합니다, 이때 동적쿼리를 활용할 수 있습니다.
이후에는 page, size를 기반으로 Pageable 객체를 만들어냅니다
이후에는 간편하게 findAll을 사용하여 booleanExpression, pageable 객체를 넘겨주고, domainEntity로 반환하여 Service로 던져줍니다.
사용해 보면서 느낀 장점
- Predicate와 Pageable 객체만 넘기면 손쉽게 페이징 구현이 가능하다.
사용해 보면서 느낀 단점 (Predicate만 넘길 수 있음)
- group by 불가능
- join 불가능
즉, 조금 복잡한 케이스에 사용할 수 없다.
이런 경우에는 순수하게 쿼리를 작성하는 방법을 선택했다.
참고자료
http://querydsl.com/static/querydsl/3.7.2/reference/ko-KR/html/ch03.html
'JPA' 카테고리의 다른 글
QuerydslRepositorySupport FetchResults Deprecated 대안 (1) 2023.11.12 [JPA] Page vs Slice (1) 2023.10.08 QueryDSL으로 페이징 구현하기 (0) 2023.09.18 QueryDSL으로 동적쿼리 작성하기 (0) 2023.09.17 JPA Persistable으로 성능최적화 해보기 (0) 2023.09.04