org.springframework.data.domain.Pageable
를 입력받고 메소드 쿼리에 사용중이었는데 custom 쿼리를 사용할일이 생겨서 queryDSL 로 새로 구현했다.
Spring data jpa 의 메소드 쿼리에는 Pageable 을 넘겨주면 알아서 처리를 해주는데 queryDSL 에서는 따로 설정해야 했다.
limit, offset 은 비교적 단순했으나 orderBy 에서 추가 구현이 필요해서 이부분을 기록해 두기로 한다.
코드를 첨부한다.
@Repository
class XXCustomRepositoryImpl(
@Qualifier("xxQueryFactory")
private val xxQueryFactory: JPAQueryFactory,
) : XXQuerydslRepositorySupport(XXEntity::class.java), XXCustomRepository {
override fun findAllByCriteria(pageable: Pageable): Page<XXEntity> {
val results =
xxQueryFactory.selectFrom(xxEntity)
.distinct()
.where(
...
)
.offset(pageable.offset)
.orderBy(sort(pageable))
.limit(pageable.pageSize.toLong())
.fetch()
val countQuery = xxQueryFactory
.selectFrom(xxEntity)
.where(
...
)
return PageableExecutionUtils.getPage(results, pageable) { countQuery.fetch().size.toLong() }
}
private fun sort(page: Pageable): OrderSpecifier<*>? {
if (!page.sort.isEmpty) {
for (order in page.sort) {
val direction = if (order.direction.isAscending) Order.ASC else Order.DESC
when (order.property) {
"createdAt" -> return OrderSpecifier(direction, xxEntity.createdAt)
"updatedAt" -> return OrderSpecifier(direction, xxEntity.updatedAt)
"id" -> return OrderSpecifier(direction, xxEntity.id)
}
}
}
return null
}
}
어떤걸 사용하느냐에 따라 조금 다른데 JPAQuery 를 사용 하면 order 에 OrderSpecifier 를 사용 해야 해서 위 코드처럼 구현할 수 있다.
도메인코드를 XX 로 치환하는 과정이랑 where 절에서 컴파일에러가 날텐데 이건 알아서 해결해주세요
사실 queryDSL 를 활용한 repository 구현해는 다양한 방법이 있으니 이런 방법도 있다라는 것만 알면 될 것 같다.
더 우아하게 짤 수 있는 방법이 있으면 댓글에 알려주시면 좋을 것 같습니다.
끝!
'JPA' 카테고리의 다른 글
[JPA] @Convert 사용해서 Object를 Json 형식으로 저장하기 (0) | 2019.12.11 |
---|---|
[JPA] Differences between save() And saveAndFlush() of SpringJPA (0) | 2018.11.10 |
[JPA] save 와 saveAndFlush의 차이 (1) | 2018.11.10 |
[JPA] JPA시작하기 - JPA란? (1) | 2017.02.02 |