QueryDsl 이란?
정적 타입을 사용해서 SQL과 같은 쿼리를 생성할 수 있도록 해주는 프레임워크
사용하는 이유?
상품 검색을 하려고 한다. 이름, 설명, 가격, 수량이 있다고 생각했을 때, 조건 검색을 위해 이름, 설명, 가격, 수량을 검색할 수도 있지만, 이름+설명, 설명+가격, 가격+수량 등등.. 의 조건이 늘어나게 되면 그만큼 if문을 사용해야 하고 그만큼 쿼리가 복잡해진다.
이때 QueryDsl을 사용하면 메서드를 활용해 쉽게 동적 검색에 사용할 수 있다.
(다른 곳에도 사용한다고 하지만 여기선 알아보지 말자)
QueryDSL 설정
ext {
set('springCloudVersion', "2023.0.2")
set('querydslVersion', "5.0.0") // QueryDSL 버전 명시적으로 설정
}
dependencies {
implementation "com.querydsl:querydsl-jpa:${querydslVersion}:jakarta"
annotationProcessor "com.querydsl:querydsl-apt:${querydslVersion}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
...
}
def querydslSrcDir = 'src/main/generated'
clean {
delete file(querydslSrcDir)
}
tasks.named('test') { useJUnitPlatform() }
build.gradle에 denpendency를 추가하고 QueryDsl 버전과 저장될 위치를 지정해준다
QueryResults<Product> results = queryFactory
.selectFrom(product)
.where(
nameContains(searchDto.getName()),
descriptionContains(searchDto.getDescription()),
priceBetween(searchDto.getMinPrice(), searchDto.getMaxPrice()),
quantityBetween(searchDto.getMinQuantity(), searchDto.getMaxQuantity())
)
.orderBy(orders.toArray(new OrderSpecifier[0]))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetchResults();private BooleanExpression nameContains(String name) {
return name != null ? product.name.containsIgnoreCase(name) : null;
}QueryDSL의 BooleanExpression을 사용하여 동적 where을 구성하고 Pageable 객체로부터 정렬 및 페이징 정보를 적용해 쿼리를 실행한다.
사실 아직도 크게 감이 잘 안온다… 실습하면서 익숙해져야겠다