JAVA/Spring

Querydsl로 효율적으로 JPA 조건 쿼리 작성하기

min민 2025. 1. 21.

 

Querydsl로 효율적으로 JPA 조건 쿼리 작성하기

 

JPA를 사용할 때, Criteria API가 기본적으로 제공되지만 실무에서는 복잡하고 가독성이 떨어지는 문제로 인해

사용이 어렵다.

 

이를 해결하기 위해 많은 개발자들이 **Querydsl**을 선택한다. Querydsl은 타입 세이프하며,

가독성이 뛰어난 쿼리 작성 방식을 제공한다.

 

 

 

 

 

Querydsl이란?

Querydsl은 Java 기반 ORM 프레임워크에서

복잡한 동적 쿼리를 간결하고 가독성 있게 작성할 수 있도록 돕는 라이브러리다.

 

 

JPQL 기반의 쿼리를 Java 코드로 작성하며, 컴파일 시점에 오류를 검출할 수 있어 안정성을 높인다.

 

 

 

 

 

 

Querydsl을 사용하는 이유

 

 

1. 가독성

Criteria API는 메서드 체이닝 방식으로 쿼리를 작성하기 때문에 코드가 길고 복잡해진다.

반면 Querydsl은 메서드 체이닝보다 간단한 문법으로 작성할 수 있다.

 

 

 

2. 타입 세이프

JPQL은 런타임 시점에 오류를 발견할 수 있다.

Querydsl은 컴파일 시점에 오류를 확인해 안전한 쿼리 작성을 보장한다.

 

 

 

3. 동적 쿼리 작성

다양한 조건에 따라 쿼리를 동적으로 생성해야 하는 경우,

Querydsl의 빌더 패턴은 뛰어난 유연성을 제공한다.

 

 

 

 

 

예시: 회원 검색 조건 동적 쿼리

아래는 Querydsl을 사용하여 회원을 검색하는 예제다.

 

1. 기본 설정

Querydsl을 사용하려면, Gradle 또는 Maven에 다음 의존성을 추가한다.

gradle
dependencies {
    implementation 'com.querydsl:querydsl-jpa'
    annotationProcessor 'com.querydsl:querydsl-apt:jpa'
}

 

빌드 후, JPA 엔터티 클래스에 대응하는 Q 클래스를 생성해야 한다

 

 

 

2. 코드 작성

아래는 Querydsl을 사용하여 회원 검색 조건을 작성한 예시다.

public List<Member> searchMembers(String name, Integer age) {
    JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
    QMember member = QMember.member;

    return queryFactory.selectFrom(member)
            .where(
                name != null ? member.name.eq(name) : null,
                age != null ? member.age.eq(age) : null
            )
            .fetch();
}

 

- QMember는 Querydsl이 자동 생성한 클래스다.

- where 조건에 null 값을 허용해 조건을 동적으로 추가한다.

- fetch()는 쿼리 결과를 리스트로 반환한다.

 

 

 

 

Querydsl로 Criteria API 비교

아래는 동일한 동적 쿼리를 Criteria API로 작성한 코드다.

public List<Member> searchMembers(String name, Integer age) {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Member> cq = cb.createQuery(Member.class);
    Root<Member> member = cq.from(Member.class);

    List<Predicate> predicates = new ArrayList<>();
    if (name != null) {
        predicates.add(cb.equal(member.get("name"), name));
    }
    if (age != null) {
        predicates.add(cb.equal(member.get("age"), age));
    }

    cq.where(predicates.toArray(new Predicate[0]));

    return entityManager.createQuery(cq).getResultList();
}

 

 

 

Criteria API는 코드의 양이 많고 복잡하며, 직관성이 떨어진다.

반면 Querydsl은 간결하게 작성할 수 있다.

 

 

 

Querydsl 사용 시 주의사항

 

1. 빌드 자동화
Q 클래스를 생성하는 빌드 과정을 정확히 설정해야 한다. 빌드 설정이 올바르지 않으면 컴파일 오류가 발생할 수 있다.

 

2. 의존성 관리
Querydsl의 버전과 JPA의 호환성을 고려해 의존성을 관리해야 한다.

 

3. 복잡한 동적 쿼리
복잡한 조건이 많은 경우 BooleanBuilder를 활용하면 관리하기 쉽다.

 

BooleanBuilder builder = new BooleanBuilder();
if (name != null) {
    builder.and(member.name.eq(name));
}
if (age != null) {
    builder.and(member.age.eq(age));
}
return queryFactory.selectFrom(member)
        .where(builder)
        .fetch();

 

 

 

 

총 정리

Querydsl은 JPA를 사용할 때 복잡한 동적 쿼리를 효율적으로 작성할 수 있는 강력한 도구다.

 

타입 세이프와 가독성을 모두 갖춘 Querydsl을 활용해 유지보수하기 쉬운 코드를 작성하는것이 추천된다.

댓글