QueryDSL이란 ?
SQL, JPQL 등을 코드로 작성할 수 있도록 해주는 프레임워크로 쿼리를 type-safe(컴파일시 에러 체크 가능)하게 Java 코드로 작성할 수 있습니다.
QueryDSL은 동적 쿼리를 아주 편리하게 작성할 수 있어 복잡한 동적 쿼리를 사용해야 할 때 QueryDSL을 사용하고
단순한 경우에는 Spring Data JPA를 사용합니다.
QueryDSL은 JPA가 제공하는 JPQL을 코드로 작성할 수 있도록 도와주는 빌더 역할을 하기 때문에 JPQL의 문법에 대한 이해가 필요합니다.
SQL과 JPQL의 문제점
QueryDSL을 이해하기 전에 먼저 SQL과 JPQL의 문제점을 알아봅시다.
# SQL
String sql = "select id, item_name, price, quantity from item";
# JPQL
String jpql = "select i from Item i";
SQL, JPQL은 문자열으로 Type-check가 불가능합니다.
그래서 만약 쿼리에 오류가 있을 시 컴파일 시점에 오류를 잡을 수 없어 애플리케이션을 실행한 후에야 오류를 발견할 수 있습니다.
QClass
QueryDSL은 컴파일 단계에서 Entitiy를 기반으로 QClass를 생성하는데
JPAAnnotationProcessor 가 컴파일 시점에 작동해서 @Entity 등등의 어노테이션을 찾아 해당 파일들을 분석해서 QClass를 만들어 줍니다.
그리고 이 Entity 클래스와 매핑되는QClass를 기반으로 쿼리를 실행합니다.
QueryDSL 장점
문자가 아닌 코드로 작성하여 컴파일 시점에 오류를 잡을 수 있습니다. ( IDE의 도움 )
또한 select, from, where 등 쿼리 작성에 필요한 키워드들을 메서드 형식으로 제공하여 단순하고 쉽게 작성할 수 있습니다.
QueryDSL은 주로 JPA와 함께 많이 사용하며 가장 장점이라 할 수 있는 부분은 동적 쿼리를 아주 편리하게 작성할 수 있습니다.
아래는 동적 쿼리를 작성한 예시로
검색 조건에 itemName이 있을 시 like로 입력한 조건에 맞는 객체 찾고
검색 조건에 maxPrice가 있을 시 검색한 maxPrice 보다 loe ( <= ) 작거나 같은 객체를 찾는 동적 쿼리 문입니다.
public List<Item> findAll(ItemSearchCond cond) {
String itemName = cond.getItemName();
Integer maxPrice = cond.getMaxPrice();
return query
.select(QItem.item)
.from(QItem.item)
.where(likeItemName(itemName), maxPrice(maxPrice))
.fetch(); // fetch() : 리스트로 결과를 반환
}
private BooleanExpression likeItemName(String itemName) {
if (StringUtils.hasText(itemName)) {
return QItem.item.itemName.like("%" + itemName + "%");
}
return null;
}
private BooleanExpression maxPrice(Integer maxPrice) {
if (maxPrice != null) {
return QItem.item.price.loe(maxPrice);
}
return null;
}
QueryDSL 설정
이 설정 방법은 빌드 옵션이 InteliJ IDEA일 때 설정 방법입니다.
1. build.gradle에 아래 의존성 추가
dependencies {
//Querydsl 추가
implementation 'com.querydsl:querydsl-jpa'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api
}
2. gradle의 작업 옵션에서 아래의 두 작업을 clean -> complie.java로 차례대로 실행
3. QClass생성 확인한 후 애플리케이션 한번 실행
프로젝트의 아래의 경로에서 Entity 클래스의 이름앞에 Q가 붙은 QClass가 생성됐는지 확인합니다. ( 이 프로젝트에서 @Entity 클래스의 이름은 Item )
생성이 됐다면 어플리케이션을 한번 실행 합니다.
이제 QueryDSL의 설정이 완료되었습니다.
QClass를 삭제할 시
IntelliJ IDEA 옵션을 선택하면 src/main/generated 에 파일이 생성되고, 필요한 경우 Q파일을 직접 삭제해야 합니다.
gradle에 아래 스크립트를 추가하면 gradle clean 명령어를 실행할 때 src/main/generated 의 파일도 함께 삭제해줍니다.
//Querydsl 추가, 자동 생성된 Q클래스 gradle clean으로 제거
clean {
delete file('src/main/generated')
}
'◼ JPA' 카테고리의 다른 글
[JPA] 엔티티 매핑 어노테이션과 속성 값 정리 (0) | 2023.06.05 |
---|---|
[JPA] 데이터베이스 초기화 전략 (ddl auto 옵션) (0) | 2023.06.04 |
[JPA] dialect란? (0) | 2023.06.04 |
[JPA] 내부 동작 방식 (feat. 영속성 컨텍스트란?) (0) | 2023.06.02 |
[JPA] JPA란 ? 그리고 Spring Data JPA (0) | 2023.04.24 |