인프런 커뮤니티 질문&답변
QueryDSL Pageable 질문
작성
·
1K
0
안녕하세요, 강의 잘 듣고 있습니다.
동적 쿼리 구성을 하려다가
기존에
findByName(name: String, pageable: Pageable)
이라는 함수를 써서 쉽게 sorting 및 pagination 을 구현했는데요.
영상에서처럼 검색 조건이 늘어나서 QueryDSL 로 바꾸려고 하는데, 혹시 pageable 을 쉽게 QueryDSL 에서 구현하는 방법이 있을까요?
퀴즈
JPQL이나 Spring Data JPA의 메서드 이름을 이용한 쿼리 작성 방식의 주된 단점은 무엇일까요?
데이터베이스 종류에 따라 쿼리 문법이 달라진다.
컴파일 시점에는 오류를 감지하기 어렵다.
성능 최적화가 어렵다.
복잡한 조인 쿼리를 작성할 수 없다.
답변 2
5
안녕하세요~! Tony님!!! ㅎㅎㅎ 아이고~~ 좋은 질문이십니다!!!
우선 간단하게 Pageable 을 바로 사용하기는 어려워 다음과 같이 limit / offset으로 치환해주어야 합니다!
fun findAll(pageable: Pageable): List<Book> {
return queryFactory.select(book)
.from(book)
.limit(pageable.pageSize.toLong())
.offset(pageable.offset)
.fetch()
}
하지만~~ Kotlin의 Extension function을 활용하면 다음과 같은 유틸성 함수를 만들 수 있고 모든 코드에서 Pageable을 바로 사용하는 것처럼 쓸 수 있습니다!
// 유틸 파일에 모아두기!
fun <T> JPAQuery<T>.withPageable(pageable: Pageable): JPAQuery<T> {
return this.limit(pageable.pageSize.toLong())
.offset(pageable.offset)
}
// 이제 다른 모든 Repository에서는 다음과 같이 활용 가능
fun findAll(pageable: Pageable): List<Book> {
return queryFactory.select(book)
.from(book)
.withPageable(pageable)
.fetch()
}
위와 같이 확장함수를 잘 활용하 매우 편리한 개발이 가능하더라고요!! 좋은 질문 감사합니다 ㅎㅎㅎㅎ 또 궁금하신 점 있으시면 편하게 질문 주세요~! 감사합니다! 😊
0
친절한 답변 너무 감사합니다!
제가 찾아보다보니까 이런 방법도 있던데, 혹시 많이 사용하는 방법일까요?
QuerydslRepositorySupport 를 상속해서 querydsl (getQuerydsl()) 을 가지고 applyPagination 을 하면 따로 유틸성 함수 추가 없이 사용이 가능하더라구요..!
@Component
class ContentQuerydslRepository<T>(
private val queryFactory: JPAQueryFactory
) : QuerydslRepositorySupport(Content::class.java) {
fun findContent(
title: String?, dtype: String?,
category: String?, pageable: Pageable
): List<Content> {
val query = queryFactory
.selectFrom(content)
.where(
title?.let { content.title.contains(title) },
dtype?.let { content.dtype.eq(ContentType(dtype)) },
category?.let { content.category.eq(ContentCategory(category)) },
)
return querydsl!!.applyPagination(pageable, query).fetch()
}
}





저는 개인적으로 많이 사용하지 않습니다! 그 이유는 1) 상속하는 것 자체가 약간 번거롭기도 하고, 2) 도메인 클래스 (Class<?>)를 넣어줘야 하는데 쿼리가 복잡해질 수록 N개의 Entity가 사용되기도 하기 때문이에요!!
유틸성 함수 같은 경우는 한 번만 추가하면 계속 사용할 수 있다보니, 크게 불편함을 느끼지 못하고 있습니다 ㅎㅎㅎㅎㅎ