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 동작 확인하기


'Backend > SpringBoot' 카테고리의 다른 글
| [SpringBoot] SpringInitilaizr 프로젝트 생성 후 gradle 빌드 초기 세팅 (1) | 2024.10.15 |
|---|---|
| [Linux/Docker] Redis, MySQL Docker 이미지를 사용해 시스템 사용해보자 (0) | 2024.08.23 |
| [SpringBoot] JUnit을 사용해 테스트 코드를 작성해보자 (0) | 2024.08.22 |
| [SpringBoot] MariaDB 데이터베이스를 연동해보자 (0) | 2024.08.22 |
| [SpringBoot] 로깅 라이브러리 Logback을 이용해 로그를 확인해보자 (0) | 2024.08.22 |