QueryDSL 이란

QueryDsl은 하이버네이트 쿼리 언어(HQL: Hibernate Query Language)의 쿼리를 타입에 안전하게 

생성 및 관리해주는 프레임워크이다.

QueryDsl 과 SpringDataJPA 를 함께 사용하여 기존 JPA 문제점인 복잡한 쿼리 및 동적 쿼리 작성의 한계를 보완할 수 있다.

[ QueryDsl의 장점 ]

  1. 쿼리를 자바 코드로 작성하므로 문법 오류를 컴파일 시점에 잡아낼 수 있다.
  2. 복잡한 쿼리나 동적 쿼리를 편리하게 작성할 수 있다.
  3. 인텔리제이와 같은 IDE의 자동 완성 기능의 도움을 받을 수 있다.

아래의 두 코드는 동일하게 작동하는 코드이다.

위는 NativeQuery 인데 문자열로 쿼리를 작성하기 때문에 실수의 여지가 많다.

아래처럼 QueryDsl 사용 시 자바 코드로 쿼리를 작성하므로 컴파일 시점에서 문법 오류를 잡아낼 수 있다.

@Query("select o from Order o where o.registeredDateTime >= :startDateTime" +
        " and o.registeredDateTime < :endDateTime" +
        " and o.orderStatus = :orderStatus")
List<Order> findOrdersBy(@Param("startDateTime") LocalDateTime startDateTime,
                         @Param("endDateTime") LocalDateTime endDateTime,
                         @Param("orderStatus") OrderStatus orderStatus);
@Override
public List<Order> findOrdersBy(LocalDateTime startDateTime, 
                            LocalDateTime endDateTime, 
                            OrderStatus orderStatus) {
    return jpaQueryFactory
        .selectFrom(order)
        .where(order.registeredDateTime.between(startDateTime, endDateTime.minusNanos(1)),
                order.orderStatus.eq(orderStatus))
        .fetch();
}

 


QueryDsl 의존성 추가

1. gradle 의 plugin 사용 시

전엔 Querydsl 라이브러리를 사용하려면 아래처럼 이것저것 복잡한 설정을 했어야했다.

구닥다리 방법이니 대충 눈으로만 보고 넘어가도 좋다.

 

build.gradle

plugins {
   id 'java'
   id 'org.springframework.boot' version '2.7.8'
   id 'io.spring.dependency-management' version '1.0.15.RELEASE'
   //querydsl 추가
   id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
}
apply plugin: "com.ewerk.gradle.plugins.querydsl"
//querydsl 추가
implementation 'com.querydsl:querydsl-jpa'
//querydsl 추가
implementation 'com.querydsl:querydsl-apt'
//querydsl 추가 시작
def querydslDir = "$buildDir/generated/querydsl"
querydsl {
   library = "com.querydsl:querydsl-apt"
   jpa = true
   querydslSourcesDir = querydslDir
}
sourceSets {
   main.java.srcDir querydslDir
}
configurations {
   querydsl.extendsFrom compileClasspath
}
compileQuerydsl {
   options.annotationProcessorPath = configurations.querydsl
}
//querydsl 추가 끝

 

2. gradle 의 Annotation processor 와 Querydsl

간단히 요약하자면 기존엔 Querydsl 라이브러리를 쓰기 위해서는 gradle 의 plugin 을 써야했지만

이젠 annotationProcessor 을 사용하여 쉽고 편리하게 의존성을 추가한다.

자세한건 허니몬님 블로그를 참고하고 코드로 넘어가겠다.

 

build.gradle

// querydsl
implementation "com.querydsl:querydsl-core"
implementation "com.querydsl:querydsl-jpa"

// querydsl JPAAnnotationProcessor 사용 지정
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa" 
// java.lang.NoClassDefFoundError(javax.annotation.Entity) 발생 대응
annotationProcessor "jakarta.persistence:jakarta.persistence-api" 
// java.lang.NoClassDefFoundError (javax.annotation.Generated) 발생 대응
annotationProcessor "jakarta.annotation:jakarta.annotation-api"

 

이렇게만 추가하고 코끼리를 눌러서 gradle 을 최신화 해준다.

이후 아래의 순서대로 눌러준다.

 

 

그리고 generated 의 annotationProcessor 폴더를 확인해서 Q 클래스 생성을 확인하면 성공이다.

 

추가로 main 의 generated 폴더에도 제대로 생성이 되었는지 확인한다.

이렇게하여 gradle 의존성 추가 및 Q 클래스 생성 확인까지 마쳤다.

만약 main 의 generated 폴더에 Q 클래스 생성이 안된다면 여기를 참고하자.

 


사용자 정의 리포지토리 설정

지금까지 QueryDsl 을 사용할 기본준비를 마쳤다.

하지만 JPA 와 함께 사용하기 위해서는 사용자 정의 리포지토리(CustomRepository) 설정이 필요하다.

 

[ 사용자 정의 리포지토리 사용법 ]

  1. QueryDslConfig 작성
  2. 사용자 정의 인터페이스 작성
  3.  사용자 정의 인터페이스 구현체 생성
  4.  스프링 데이터 리포지토리에 사용자 정의 인터페이스 상속

그림으로 표현하면 아래와 같다.

 

1. QueryDslConfig

가장 먼저 QueryDsl 을 JPA 와 함께 사용하기 위해 필요한 구현체인 JPAQueryFactory 의 빈 등록을 위한 Config 설정이다.

@Configuration
public class QueryDslConfig {

    @PersistenceContext
    public EntityManager em;

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

 

2. 인터페이스 PostRepositoryCustom 

사용자 정의 리포지토리를 설정해야한다.

public interface PostRepositoryCustom {

    List<Post> getList(PostSearch postSearch);
}

 

3. 구현체 PostRepositoryImpl

@Repository
@RequiredArgsConstructor
public class PostRepositoryImpl implements PostRepositoryCustom{

    private final JPAQueryFactory jpaQueryFactory;

    @Override
    public List<Post> getList(PostSearch postSearch) {
        return jpaQueryFactory.selectFrom(QPost.post)
            .limit(postSearch.getSize())
            .offset(postSearch.getOffset())
            .orderBy(QPost.post.id.desc())
            .fetch();
    }
}

 

3. PostRepository 에 PostRepositoryCustom 상속

public interface PostRepository extends JpaRepository<Post, Long>, PostRepositoryCustom {
}

 

 

출처)

허니몬님 블로그

 

[gradle] 그레이들 Annotation processor 와 Querydsl - I'm honeymon(JiHeon Kim).

이 글에서 다룰 예정인 ‘Querydsl’과 ‘Annotation processor’ 에 관한 내용도, 스프링 부트를 버전업하는 과정에서 겪게 된다. 사내 개발기기 교체주기가 되어 새로운 맥북을 받고 스프링 부트 버전

honeymon.io

 

김영한님 QueryDsl 강의

 

 

실전! Querydsl - 인프런 | 강의

Querydsl의 기초부터 실무 활용까지, 한번에 해결해보세요!, 복잡한 쿼리, 동적 쿼리는 이제 안녕! Querydsl로 자바 백엔드 기술을 단단하게. 🚩 본 강의는 로드맵 과정입니다. 본 강의는 자바 백엔

www.inflearn.com

 

'백엔드 > 연습' 카테고리의 다른 글

QueryDSL 적용하기: gradle-kotlin  (0) 2024.05.13
포트원 API 사용해보기  (0) 2024.04.04
plain-jar 파일 생성 방지  (0) 2024.01.16
JWT 발급해보기  (0) 2023.10.04
H2 DB 사용해보기  (0) 2023.09.24

+ Recent posts