우당탕탕

Spring Boot에서 Querydsl 도입, 직접 해보고 정리한 절차와 팁 본문

Tech/Spring

Spring Boot에서 Querydsl 도입, 직접 해보고 정리한 절차와 팁

모찌모찝 2026. 6. 3. 20:24

저도 처음에 Spring Boot 프로젝트에 Querydsl을 도입할 때 생각보다 삽질이 많았거든요. 쿼리 작성이 훨씬 편해진다는 이야기에 도입을 결심했는데, 설정부터 코드 작성까지 한 번에 깔끔하게 정리된 자료가 별로 없더라고요.

그래서 직접 제가 경험한 걸 바탕으로 Querydsl 도입 절차를 단계별로 정리해봤습니다. 설정부터 빌드, 코드 작성, 그리고 흔히 겪는 문제 해결까지 이 글만 보면 충분할 거예요.

개발 환경 / 버전 정보

제가 사용한 환경은 Java 17, Spring Boot 3.1.0, 그리고 Gradle 8.0였습니다. 이 조합에서 Querydsl 5.0.0 버전을 도입했어요.

1단계: build.gradle에 Querydsl 의존성 추가

사실 이 부분에서 많이들 헷갈려하시는데, 저는 이렇게 했어요. 먼저 build.gradle에 Querydsl 관련 의존성을 추가합니다.

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.1.0'
    id 'io.spring.dependency-management' version '1.1.0'
}

dependencies {
    implementation 'com.querydsl:querydsl-jpa:5.0.0'
    implementation 'jakarta.persistence:jakarta.persistence-api:3.1.0'
    annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jpa'
    annotationProcessor 'jakarta.annotation:jakarta.annotation-api:2.1.1'
    // 기타 필요한 의존성
}

특히 annotationProcessor가 빠지면 Q파일 생성을 못해서 계속 막혔어요. 꼭 넣으셔야 합니다.

2단계: Gradle 플러그인 설정 및 소스 폴더 추가

그다음에 Q클래스가 제대로 생성되려면 빌드 시에 annotationProcessor가 실행돼야 하거든요. 그래서 Gradle에 다음 설정을 추가했어요.

java {
    sourceSets {
        main {
            java {
                srcDir 'build/generated/querydsl'
            }
        }
    }
}

task generateQueryDSL(type: JavaCompile) {
    source = sourceSets.main.java
    classpath = configurations.annotationProcessor
    options.annotationProcessorPath = configurations.annotationProcessor
    destinationDir = file('build/generated/querydsl')
    options.compilerArgs = [
        '-proc:only',
        '-processor', 'com.querydsl.apt.jpa.JPAAnnotationProcessor'
    ]
}

compileJava.dependsOn generateQueryDSL

이렇게 하면 빌드 시 자동으로 Q파일이 build/generated/querydsl에 생성돼요. 이 경로를 인텔리제이에도 소스 폴더로 등록해줘야 제대로 인식됩니다.

3단계: 인텔리제이에서 Generated Sources 경로 등록하기

생성된 Q파일을 인텔리제이가 인식 못 하면 코드 자동완성도 안 되고, 에러 표시가 계속 떠요. 그래서 build/generated/querydsl 폴더를 다음 순서로 설정했습니다.

  • 프로젝트 뷰에서 해당 폴더 우클릭
  • Mark Directory as → Generated Sources Root 선택

이렇게 하니 빌드 후 바로 Q클래스가 인텔리제이에서 자동완성되고 오류도 사라졌습니다.

4단계: 실제 Entity에 적용해보기

이제 Q클래스가 제대로 생성되면 실전에서 사용해봐야겠죠? 저는 이렇게 간단한 회원 엔티티를 만들었어요.

@Entity
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;

    private int age;

    // getter, setter 생략
}

그리고 Repository에 Querydsl 지원을 추가하기 위해 QuerydslPredicateExecutor를 상속하거나 직접 커스텀 리포지토리를 만들었는데요, 저는 편리성 때문에 Spring Data JPA의 Querydsl 지원을 사용했습니다.

public interface MemberRepository extends JpaRepository<Member, Long>, QuerydslPredicateExecutor<Member> {
}

이렇게 하면 기본적인 Querydsl 기능을 바로 사용할 수 있어요.

5단계: Q클래스를 활용해 직접 쿼리 작성해보기

이 단계가 사실 가장 재밌더라고요. Q클래스를 활용해서 원하는 조건으로 쿼리를 만드는 과정입니다. 간단한 예시를 보여드릴게요.

@Autowired
private EntityManager em;

public List<Member> findByUsernameAndAge(String username, int age) {
    JPAQueryFactory queryFactory = new JPAQueryFactory(em);
    QMember m = QMember.member;

    return queryFactory.selectFrom(m)
        .where(m.username.eq(username)
            .and(m.age.gt(age)))
        .fetch();
}

이렇게 하면 username이 특정 값이고, 나이가 특정 값 이상인 회원을 쉽게 조회할 수 있죠. 코드가 훨씬 깔끔해졌어요.

여기서 삽질했던 부분들

처음에 빌드해도 Q클래스가 생성 안 되는 문제가 있었어요. 에러 메시지는 없는데 아무런 Q파일도 안 만들어져서 정말 한참 헤맸는데, annotationProcessor 의존성을 안 넣은 게 원인이었더라고요.

annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jpa'

이걸 안 넣으면 아무리 빌드해도 계속 Q클래스가 생성 안 돼서 딱히 오류도 없이 당황했어요.

또한 인텔리제이에서 generated 소스 폴더를 마킹 안 하면 빌드 성공해도 편집기에서는 오류로 표시돼서 꽤나 헷갈렸습니다.

심화: JPAQueryFactory 빈으로 등록해 재사용하기

처음에는 매번 함수 내에서 JPAQueryFactory를 새로 만들었는데, 이게 생각보다 비효율적이더라고요. 그래서 @Bean으로 등록해서 DI 받는 방법도 써봤습니다.

@Configuration
public class QuerydslConfig {

    @PersistenceContext
    private EntityManager em;

    @Bean
    public JPAQueryFactory jpaQueryFactory() {
        return new JPAQueryFactory(em);
    }
}

이렇게 등록해두니 서비스 클래스에서 매번 새로 만드는 번거로움 없이 깔끔하게 쓸 수 있었어요.

자주 물어보시는 것들

Q. Q클래스가 안 만들어져요, 빌드만 하면 되나요?

A. 빌드하면 보통 생성되긴 하는데, 의존성에 annotationProcessor 'com.querydsl:querydsl-apt:...:jpa'가 있어야 해요. 그리고 IDE에서 생성 경로를 'Generated Sources'로 마킹해야 인식됩니다.

Q. Querydsl과 Spring Data JPA 같이 써도 되나요?

A. 네, Querydsl을 Spring Data JPA Repository에서 확장 가능해서 둘이 아주 잘 어울려요. 필요하면 커스텀 리포지토리를 만들어 복잡한 쿼리도 깔끔하게 구현할 수 있습니다.

Querydsl 도입하면서 정말 편리해진 점은 동적 쿼리를 깔끔하게 만들 수 있다는 거였어요. 자바 코드로 타입 안정성을 보장하면서 쿼리 조립도 쉬워서 코드를 더 깔끔하게 관리할 수 있더라고요.

요즘 Spring Boot 프로젝트에선 필수처럼 느껴지는 기술이라 실제로 써보면서 꼭 한 번 도입해보시길 추천합니다.

Comments