JPA 혹은 Spring Data JPA 를 사용해서 프로젝트를 진행하다 보면, 특정 경우에서 오는 불편함을 지울 수 없습니다.
예를 들면, 검색쿼리 같이 조건문이 여러 조합으로 되는 경우나, Entity 를 조회하는 것이 아닌 DTO를 조회하는 경우 등과 같은 경우가 있습니다. 이런 단점을 보완하기 위해, JPA를 사용하는 곳에선 QueryDSL 을 같이 사용하는 곳이 많다고 합니다.
저 또한, QueryDSL 을 사용하면서 사이드 프로젝트를 진행하는데, 설정방법을 매번 찾아보기 번거로워 블로깅해봅니다.
0. 구성환경
QueryDSL 에서는 maven 에 대한 가이드는 제공하면서... gradle에 대한 가이드는 제공해주지 않습니다...
(이유는 모르겠슴돠...ㅠ 아시는 분 댓글 부탁드려용 ㅎ)
그래서 기존에 QueryDSL 설정을 구글에 검색하면 많은 방법이 나오지만, 대부분 SpringBoot 2.x.x 버전에 java 1.8 혹은 11 기준인 글이 많습니다.
하지만, 제가 설정한 환경은 SpringBoot 3.1.0 / java 17 이니 참고 부탁드립니다.
출처 : https://lemontia.tistory.com/1089
1. build.gradle 설정
QueryDSL dependency를 추가하기 위해서 아래 내용을 추가해줘야 합니다.
dependencies {
// -- 중략 -- //
// QueryDSL
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'
}
def querydslSrcDir='src/main/generated'
clean {
delete file(querydslSrcDir)
}
tasks.withType(JavaCompile) {
options.generatedSourceOutputDirectory = file(querydslSrcDir)
}
QueryDSL 은 @Entity 이 붙은 class 와 그 class 안에 포함된 class 이름 앞에 Q 를 붙인 Q타입 class 를 생성하고, 이것을 사용할 수 있게 지원해줍니다.
위와 같이 dependency를 적용한 후, 인텔리제이의 우측 gradle 메뉴에서 "compileJava" 를 실행합니다.
그럼 하단 콘솔창에 성공표시와 함께, "src/main/generated" 밑에 Q타입의 entity 들이 생성되어 있습니다.
2. 간단한 예제 테스트
제가 현재 개발 중인 프로젝트는 상단 메뉴를 DB에서 관리하도록 설계되어 있어, 모든 최상위 메뉴 정보를 조회하는 쿼리를 아래와 같이 작성하였습니다.
-- JPQL 버전
select m from Menu m where m.parent is null order by m.order
위 쿼리를 반환하도록 하는 QueryDSL Repository 를 아래와 같이 작성해봤습니다.
@Repository
public class MenuQueryRepository {
private final JPAQueryFactory queryFactory;
public MenuQueryRepository(EntityManager em) {
this.queryFactory = new JPAQueryFactory(em);
}
public List<Menu> findTopMenus() {
return queryFactory.selectFrom(QMenu.menu)
.where(
QMenu.menu.parent.isNull()
)
.orderBy(
QMenu.menu.order.asc()
)
.stream().toList();
}
}
QueryDSL의 JPAQueryFactory는 JPA에서 사용하는 EntityManager 를 주입받아 JPQL Builder 역할을 수행해줍니다.
JPQL 작성 시 단점 중 하나로 뽑히는 순수 문자열로 쿼리를 작성하여 쿼리를 잘 못 작성한 경우, 메서드를 실행해보기 전까진 오류를 발견할 수 없다는 점을 QueryDSL 은 모두 컴파일단계에서 문법오류를 발생시킴으로써 앞의 단점을 극복합니다.
위 메서드의 테스트코드를 작성하고 테스트를 실행해봄으로써 아래와 같이 쿼리가 동작한다는 것을 알 수 있습니다.
'DB&JPA' 카테고리의 다른 글
[MySQL] 트랜잭션 격리수준 (0) | 2024.03.07 |
---|---|
[MySQL] 계정 생성 및 권한 부여, 그리고 역할 (0) | 2024.02.06 |
[JPA] JPA 쿼리 로그 및 파라미터 바인딩 확인하기 (SpringBoot3 버전) (0) | 2023.07.08 |
[JPA] @AttributeOverrides 와 @Embedded 로 간결한 도메인 객체 만들기 (0) | 2023.07.06 |
댓글