Spring Boot QueryDSL + JPA 사용해보기

Seokjun Moon·2023년 11월 13일
0

QueryDSL

카카오 테크 캠퍼스를 하면서 검색 로직을 작성할 때, 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을 사용해도 물론 구현이 가능하지만, 여러가지 단점이 존재합니다.

  1. 런타임에서 에러를 캐치해야 합니다.
  2. 동적 쿼리 생성이 복잡합니다.

카테캠 프로젝트에서도 JPQL을 사용하지 않은 이유가 동적 쿼리를 만드는 법이 쉽지 않습니다. Specification으로 보다 간결해지나, 이 또한 한눈에 로직을 파악하기란 쉽지 않습니다.

따라서!!!! QueryDSL을 도입했습니다.

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);
    }
}

이러면 설정 끝 !!! 작성하러 가봅시다.

repository

기본적으로 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을 도입하게 되었다.

profile
차근차근 천천히

0개의 댓글