Programing/JPA

Springboot 2.x + queryDSL 설정 방법

리커니 2023. 7. 18. 12:31
반응형

JPA를 사용하게 되면 Query method를 사용하면 간단한 조건의 작업들은 가능하지만 복잡한 쿼리로 작성되어야하는 로직의 경우 한계가 있습니다. 물론 어느정도 가능은 하겠지만 query method의 길이가 엄청나게 길어지겠죠.

이를 보완하기 위해 @Query, JPQL 를 사용하도 합니다. 하지만 문자열을 + 로 연결해야 하며 가독성도 떨어지고, 유지관리에 어려움이 있습니다.

 

1. Query method

List<L_OP_ATND> findByKeyUserIdAndKeyAtndYmdBetweenOrderByKeyAtndYmd(String UseId, Date first, Date last);

 

2. @Query

@Query(value = "select count(*)"
            + " from ("
            + " select *"
            + " from ("
            + " select 'ACT1' as atvtNm"
            + " , 1 as atvtCd"
            + " , t2.cd_nm as status"
            + " , t1.rct_dt"
            + " , t1.rtn_dt"
            + " , t3.venue_nm"
            + " from schema.l_op_user_mucn t1"
            + " left join kt_carbon.m_op_cd t2 on (t2.cd_grp_id = 'CD0006' and t2.cd_id = t1.rct_rtn_cd)"
            + " left join kt_carbon.g_op_venue t3 on (t3.venue_sqno = t1.venue_sqno)"
            + " where t1.user_id = :userId"
            + " and t1.rct_dt between :stDate and :edDate"
            + " union all"
            + " select 'ACT2' as atvtNm"
            + " , 2 as avtvCd"
            + " , 'save' as status"
            + " , null as rct_dt"
            + " , null as rtn_dt"
            + " , null as venune_nm"
            + " from schema.l_op_hike"
            + " where user_id = :userId"
            + " and crt_ymd between :stDate and :edDate"
            + ") st where st.atvtCd in :atvtCd) t", nativeQuery = true)
    int findActivityLogListCount(@Param("userId") String userId, @Param("atvtCd") List<Integer> atvtCd,
            @Param("stDate") Date stDate, @Param("edDate") Date edDate);

 

이런 문제점(?!) 때문에 mybatis를 혼용해서 사용하는 경우도 있습니다. 

개발하기는 편해지겠지만, 쿼리 의존적이 되고, 컴파일 시점에 오류를 파악하기도 힘들죠.

 

이런 단점들을 보완하면서 JPA를 좀 더 파워풀 하게 사용하기 위해 나온 것이 queryDSL입니다.

 

3. QueryDSL

QCat cat = QCat.cat;
QCat mate = new QCat("mate");
QCat kitten = new QCat("kitten");
queryFactory.selectFrom(cat)
    .innerJoin(cat.mate, mate)
    .leftJoin(cat.kittens, kitten)
    .fetch();

 

Unified Queries for Java.
Querydsl is compact, safe
and easy to learn.

 

QueryDSL의 슬로건 입니다.

Java용 통합쿼리. 작고 안전하며 배우기 쉽다.

 

QueryDSL은 Java JPA, MongoDB 및 SQL을 포함하여 여러 백엔드에 대해 형식이 안전한 SQL 유사 쿼리를 구성할 수 있는 프레임워크 입니다.

 

4. QueryDSL 설정방법

4.1 build.gradle 설정

// springboot 2.6 이상에서는 5.0.0 버전을 사용
buildscript {
	ext {
		queryDslVersion = "5.0.0"
	}
}
plugins {
    .
    .
    .
    //추가
	id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
}
dependencies {
    .
    .
    .
	//queryDSL 의존성 추가
	implementation "com.querydsl:querydsl-jpa:${queryDslVersion}"
	implementation "com.querydsl:querydsl-apt:${queryDslVersion}"
    .
    .
    .
}


//--------------------queryDSL 관련 추가----------------------------
def querydslDir = "$buildDir/generated/querydsl"

querydsl {
	jpa = true
	querydslSourcesDir = querydslDir
}
sourceSets {
	main.java.srcDir querydslDir
}
configurations {
	querydsl.extendsFrom compileClasspath
}
compileQuerydsl {
	options.annotationProcessorPath = configurations.querydsl
}

위와같이 build.gradle 을 추가해줍니다. 추가 후 IDE를 재실행 해줍니다.

 

4.2 compileQuerydsl 실행

IDE를 재실행 후 Gradle > Tasks > other 을 보게되면 compileQuerydsl이 생긴 것을 확인하실 수 있습니다.

 

우선 Gradle > Tasks > build > clean 을 해주시고, 그 후에 other > compileQuerydsl을 실행해 주세요.

그럼 project > build > generated 에 entity들이 자동으로 생성된 것을 확인하실 수 있습니다.

 

 

4.3 QuerydslConfig 작성

import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;


@Configuration
public class QuerydslConfig {
    @PersistenceContext
    private EntityManager entityManager;

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

repository에서 jpaQueryFactory를 쓰기위한 config 설정을 합니다.

 

 

이제 Querydsl을 사용할 준비가 끝났습니다.

다음 포스팅에서는 실제 .Querydsl을 사용하는 방법에 대해서 알아보도록 하겠습니다.

반응형