Backend/SpringBoot

[SpringBoot] QueryDSL에 대해 알아보고 사용해보자

seoraroong 2024. 8. 22. 19:15

QueryDSL

정적 타입을 이용해 SQL과 같은 쿼리를 코드로 작성할 수 있게 하는 프레임워크이다.

자바 애플리케이션에서 타입 안전한 쿼리를 작성할 수 있도록 도와주며 SQL, JPQL, MongoDB 쿼리 등 다양한 쿼리 언어에 대해 타입 안정성을 제공해, 컴파일 타임에 쿼리의 오류를 잡을 수 있다.

 

- 타입 안전한 쿼리

QueryDSL은 컴파일 타임에 쿼리의 오류를 검출할 수 있게 해준다. 

SQL, JPQL, MongoDB 등 다양한 쿼리 언어를 사용해 타입 안전한 쿼리를 작성할 수 있는 방법을 제공한다.

 

쿼리의 구문 오류가 필드 오류를 코드 작성 시점에서 발견할 수 있기 때문에 런타임 오류를 줄일 수 있다.

 

- Q 클래스

QueryDSL은 Entity에 대한 Q 클래스를 생성한다.

Q 클래스는 Entity의 필드에 대한 메타데이터를 포함하고 있으며, 쿼리를 작성할 때 필드에 대한 타입 안전한 접근을 제공한다.

 

Q로 시작하는 클래스 이름을 가지며 QProduct와 같은 형태로 Entity 클래스 Product에 대한 Q 클래스를 생성한다.

QProduct product = QProduct.product;

 

- QueryDSL 쿼리 작성

QueryDSL을 사용해 쿼리를 작성하고 실행한다. 

QueryDSL은 쿼리 빌더 패턴을 사용해 쿼리를 구성한다. 

 

JPAQuery, SQLQuery 등의 클래스를 사용해 쿼리를 생성한다.

JPAQuery<Product> query = new JPAQuery<>(entityManager);
List<Product> products = query.select(product)
                              .from(product)
                              .where(product.name.eq("Example Product"))
                              .fetch();

 

- JPA와의 통합

QueryDSL은 JPA와 통합되어 JPQL 을 사용하는 쿼리를 작성할 때에도 타입 안정성을 제공한다.

 

JPAQuery를 사용해 JPQL 쿼리를 작성하고 Entity의 Q 클래스를 통해 필드를 참조한다.

JPAQuery<Product> query = new JPAQuery<>(entityManager);
List<Product> products = query.select(QProduct.product)
                              .from(QProduct.product)
                              .where(QProduct.product.price.gt(100))
                              .fetch();

 

- SQL과의 통합

QueryDSL은 SQL 쿼리를 작성할 때에도 타입 안정성을 제공한다.

 

SQLQuery를 사용해 SQL 쿼리를 작성하고 데이터베이스 테이블에 대한 Q 클래스를 통해 필드를 참조한다.

SQLQuery<Product> query = new SQLQuery<>(connection, configuration);
QProduct product = QProduct.product;
List<Product> products = query.select(product)
                              .from(product)
                              .where(product.price.gt(100))
                              .fetch();

 

- Spring과의 통합

Spring Data와 통합해 QueryDSL을 사용할 수 있다.

Spring Data JPA와 함께 사용될 때는 QuerydslPredicateExecutor를 통해 동적 쿼리를 쉽게 생성할 수 있다.

 

Repository 인터페이스에 QueryDSL을 통합해 복잡한 쿼리 작업을 더 간편하게 처리할 수 있다.

public interface ProductRepository extends JpaRepository<Product, Long>, QuerydslPredicateExecutor<Product> {
}

 

- SpringBoot와 QueryDSL 설정

SpringBoot 프로젝트에서 spring-boot-starter-data-jpa와 querydsl 의존성을 추가해 QueryDSL을 사용하는 JPA 쿼리 메서드를 쉽게 작성할 수 있다.

<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-jpa</artifactId>
    <version>5.0.0</version>
</dependency>
@Configuration
@EnableJpaRepositories
public class QuerydslConfig {
    
    @Bean
    public JPAQueryFactory jpaQueryFactory(EntityManager em) {
        return new JPAQueryFactory(em);
    }
}

 

 

 

 

QueryDSL을 사용하기 위한 관련 의존성 추가하기

 

- 5.1.0 version에 해당하는 의존성 코드를 pom.xml의 dependencies에 추가하기

 

- QueryDSL을 사용하기 위한 APT 플러그인 추가

  • pom.xml의 <plugins> 태그에 추가

 

→ APT 플러그인을 추가하는 과정에서 문제 발생

→ 스프링 부트 3.0 부터는 javax 패키지가 jakarta로 변경되어 잘못된 의존성(javax 패키지로 불러옴)을 불러와서 예외가 발생하는 문제

 

시도해본 방법 1) pom.xml의 <dependencies>에 다음과 같은 내용 추가하기

🤯 그러나 maven compile 시 오류 발생

 

최종 Trouble Shooting

        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
            <version>5.1.0</version>
            <classifier>jakarta</classifier>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
            <version>5.1.0</version>
            <classifier>jakarta</classifier>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-core</artifactId>
            <version>5.1.0</version>
        </dependency>

스프링 3 버전, Java 17버전 이후로부터 javax가 jakarta로 넘어가면서 위와 같은 Plugin은 deprecated 되었다 → Plugin은 일절 사용하지 않는다.

→ 일일이 classifier를 추가하는 방법을 사용한다

 

‼️ 위에서 APT 플러그인을 추가하기 위해 플러그인 내용을 추가하는 방법 사용 X

 

5.1.0 버전으로 querydsl-apt, querydsl-jpa, querydsl-core 의존성을 추가했으므로 version은 5.1.0으로 작성해준다.

 

의존성 작성 완료 후 Maven → compile 실행 완료되면 QProduct라는 Q 클래스가 생긴다.

 

QProduct가 생기지 않는 경우가 있다!

 

위 문제 Trouble Shooting

[File] → [Project Structure]

QProduct 클래스가 생겨야 할 위치인 [generated-sources] 우클릭

→ [Sources] 체크 후 Apply

[Maven] → [Clean] → [Run Maven Build]

[Maven] → [Compile] 하면 QProduct가 잘 생성되는 것을 확인할 수 있다.

 

 

테스트 코드를 통해 QueryDSL 동작 확인하기