실무에서 복잡한 쿼리를 만나게 되었고 이를 효율적으로 사용하기 위한 QueryDsl에 대해 공부하고 정리하기 위해 작성한 포스트입니다.
QueryDSL 이란?
- SQL, JPQL을 코드로 작성할 수 있도록 도와주는 빌더 API
- 오픈소스
- @Entitiy를 가지고 QEntitiy.java 라는 QueryDSL 전용 객체를 만들어 쉽게 코드를 짤 수 있다.
QueryDSL의 장점
- SQL, JPQL처럼 문자열이 아닌 코드로 작성가능
- 컴파일시점에 문법 오류를 잡을 수 있음
- IDE를 통해 코드 자동완성 도움을 받을 수 있음
- 쿼리를 함수로 추출해서 재사용 할 수 있음
- *동적 쿼리
QueryDSL의 동적 쿼리
- *QueryDSL을 쓰는 진짜 이유다
- 기존의 JPQL은 정적 쿼리로, 문자열 더하기 방식이 어렵다.
- 반면 QueryDSL은 코드를 더하는 것 이기 때문에 더 쉽다.
- 원하는 필드만 뽑아서 DTO로 뽑아내는 기능도 QueryDSL이 지원
- BooleanBuilder에 조건을 넣고 쿼리를 실행 시킬수 있음(조건을 넣을 수 있는 불린빌더로 동적 쿼리가 생성된다)
동적쿼리는 BooleanBuilder 대신 BooleanExpression
- if문을 나열하는 형식의 BooleanBuilder 대신 BooleanExpression을 사용해 메소드 형태로 사용하기
(Builder 방식은 if 가 늘어나면 한눈에 보기 어려움)
@Override
public List<Academy> findDynamicQuery(String name, String address, String phoneNumber) {
BooleanBuilder builder = new BooleanBuilder();
if (!StringUtils.isEmpty(name)) {
builder.and(academy.name.eq(name));
}
if (!StringUtils.isEmpty(address)) {
builder.and(academy.address.eq(address));
}
if (!StringUtils.isEmpty(phoneNumber)) {
builder.and(academy.phoneNumber.eq(phoneNumber));
}
return queryFactory
.selectFrom(academy)
.where(builder)
.fetch();
}
@Override
public List<Academy> findDynamicQueryAdvance(String name, String address, String phoneNumber) {
return queryFactory
.selectFrom(academy)
.where(eqName(name),
eqAddress(address),
eqPhoneNumber(phoneNumber))
.fetch();
}
private BooleanExpression eqName(String name) {
if (StringUtils.isEmpty(name)) {
return null;
}
return academy.name.eq(name);
}
private BooleanExpression eqAddress(String address) {
if (StringUtils.isEmpty(address)) {
return null;
}
return academy.address.eq(address);
}
private BooleanExpression eqPhoneNumber(String phoneNumber) {
if (StringUtils.isEmpty(phoneNumber)) {
return null;
}
return academy.phoneNumber.eq(phoneNumber);
}