카카오 테크 캠퍼스를 하면서 검색 로직을 작성할 때, JPA의 기능 중 하나인 Specification을 이용하여 구현했습니다. 쿼리문을 동적으로 추가할 수 있지만, 가독성이 좋지 못했습니다.
join 패치를 하기 위해서는
Fetch<Portfolio, Planner> fetch = null;
if (query.getResultType() != Long.class && query.getResultType() != long.class) {
fetch = root.fetch("planner");
}
이렇게 사용해야 하고, 조건을 추가하기 위해서는
criteriaBuilder.equal(root.get("location"), request.location());
이렇게 작성하는데, 코드 가독성이 좋지 않습니다.
JPQL을 사용해도 물론 구현이 가능하지만, 여러가지 단점이 존재합니다.
카테캠 프로젝트에서도 JPQL을 사용하지 않은 이유가 동적 쿼리를 만드는 법이 쉽지 않습니다. Specification으로 보다 간결해지나, 이 또한 한눈에 로직을 파악하기란 쉽지 않습니다.
따라서!!!! QueryDSL을 도입했습니다.
SQL 쿼리문을 자바 코드로 작성할 수 있도록 해주는 라이브러리입니다! 그럼 세팅을 해보면
우선 의존성을 추가합니다.
dependencies {
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
}
clean {
delete file('src/main/generated')
}
이 다음 인텔리제이 내에서 gradle > task > clean 후 compileJava를 실행하시면 됩니다.
그리고 configuration을 추가합니다.
@Configuration
public class QueryDSLConfig {
@PersistenceContext
public EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(this.entityManager);
}
}
이러면 설정 끝 !!! 작성하러 가봅시다.
기본적으로 JPA를 이용하였습니다. 엔티티 관리, DB생성 등이 자바 코드로 다 관리할 수 있어서 좋습니다 .. 데이터베이스 조회 시에만 QueryDSL을 사용합니다.
@Repository
@RequiredArgsConstructor
public class UserAccountRepositoryImpl implements UserAccountRepository {
private final JPAQueryFactory jpaQueryFactory;
private final static QUserAccount TABLE = QUserAccount.userAccount;
@Override
public Optional<UserAccount> findUserAccountByEmail(String email) {
UserAccount userAccount = jpaQueryFactory
.selectFrom(TABLE)
.where(TABLE.email.eq(email))
.fetchOne();
return Optional.ofNullable(userAccount);
}
}
짠! 조회 쿼리를 바로 만들었습니다! 어때요 간단하죠 ?! 그리고 where절에 null이 있다면, 자동으로 제외시켜서 쿼리를 생성하기 때문에 null을 신경쓰지 않아도 된다!!
아무튼 이렇게 QueryDSL을 도입하게 되었다.