Tools & Libraries/Querydsl

[Querydsl] Querydsl 시작, 기본 세팅

대기업 가고 싶은 공돌이 2024. 8. 28. 01:59

이번에 운영진으로 활동중인 TAVE에서 공식 홈페이지를 만드는 프로젝트에 참여하게 됐다.

 

지원자들의 서류를 받고 점수를 메기며, 합불을 정하는 것까지 홈페이지에서 관리자 모드로

사용 가능하게 기능을 구현하기 위해선, 복잡한 쿼리를 작성할 필요가 있어 보였고

 

프로젝트에 들어가기 전 복잡한 쿼리와 동적 쿼리에 특화 됐다는 query dsl을 공부할 필요성을 느껴

 

query dsl 강의를 듣게 됐다.

 

의존성

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.3.3'
    id 'io.spring.dependency-management' version '1.1.6'
}

group = 'study'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
       languageVersion = JavaLanguageVersion.of(17)
    }
}

configurations {
    compileOnly {
       extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'com.h2database:h2'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

    // Querydsl 추가
    implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
    annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
    annotationProcessor "jakarta.annotation:jakarta.annotation-api"
    annotationProcessor "jakarta.persistence:jakarta.persistence-api"
}

tasks.named('test') {
    useJUnitPlatform()
}

clean {
    delete file('src/main/generated')
}

// Querydsl 설정 추가
//def querydslDir = 'src/main/generated'
//
//querydsl {
//  jpa = true
//  querydslSourcesDir = querydslDir
//}
//
//sourceSets {
//  main {
//     java {
//        srcDirs = ['src/main/java', querydslDir]
//     }
//  }
//}
//
//compileQuerydsl {
//  options.annotationProcessorPath = configurations.annotationProcessor
//}

 

우선 build.gradle은 다음과 같이 설정해 주었다.

 

밑에 주석으로 써져있는 부분은 spring boot 2.X 버전에서는 필요한 부분이었지만,

3.X로 넘어가면서 자동으로 설정해주어 필요하지 않게 됐다 해서 주석 처리를 해주었다.

 

테스트

@Entity
@Getter
@Setter
public class Hello {

    @Id @GeneratedValue
    private Long id;
}

다음과 같이 기본적인 엔티티를 만들어준 이후,

 

main()이나 test() 아무 거나 실행을 시켜보면 q class가 생성되는 것을 확인할 수 있다.

 

package study.querydsl.entity;

import static com.querydsl.core.types.PathMetadataFactory.*;

import com.querydsl.core.types.dsl.*;

import com.querydsl.core.types.PathMetadata;
import javax.annotation.processing.Generated;
import com.querydsl.core.types.Path;


/**
 * QHello is a Querydsl query type for Hello
 */
@Generated("com.querydsl.codegen.DefaultEntitySerializer")
public class QHello extends EntityPathBase<Hello> {

    private static final long serialVersionUID = 1910216155L;

    public static final QHello hello = new QHello("hello");

    public final NumberPath<Long> id = createNumber("id", Long.class);

    public QHello(String variable) {
        super(Hello.class, forVariable(variable));
    }

    public QHello(Path<? extends Hello> path) {
        super(path.getType(), path.getMetadata());
    }

    public QHello(PathMetadata metadata) {
        super(Hello.class, metadata);
    }

}

 

다음과 같이 q class가 잘 생성 됐다면 기본 세팅은 무사히 된 것이다.

 

위의 q class는 코드 제너레이션이라 해서, query dsl을 활용하여 쿼리를 만들 수 있게 도와주는 

클래스라 하는데 아직은 잘 감이 안 잡힌다.

 

강의를 계속 듣다보면 알 수 있다고 한다.

 

참고로 위의 q class는 컴파일시 자동으로 생성되는 클래스기 때문에

 

q class 가 만들어지는 generated 패키지는 git에 올라가지 않도록 git.ignore에 추가시켜줘야 한다.

 

쿼리 테스트

@SpringBootTest
@Transactional
class QuerydslApplicationTests {

    @Autowired
    EntityManager em;

    @Test
    void contextLoads() {
       Hello hello = new Hello();
       em.persist(hello);

       JPAQueryFactory query = new JPAQueryFactory(em);
       QHello qHello = new QHello("h");

       Hello hello1 = query.selectFrom(qHello).fetchOne();

       Assertions.assertThat(hello1).isEqualTo(hello);

    }

}

 

다음과 같이 간단한 쿼리를 작성한 후 실행을 시켜 보았더니 무사히 통과 됐다.

 

기본설정도 모두 끝났고 쿼리도 잘 실행되는 것을 확인할 수 있었다.

라이브러리 살펴보기

쿼리 dsl의 라이브러리를 살펴보면 다음과 같이 apt와 jpa 두 개로 나뉘어져 있는 것을 확인할 수 있다.

 

apt

apt는 코드 제너레이션을 만들기 위해 사용하는 라이브러리다. 

 

코드를 실행했을 시 엔티티에 해당하는 Q엔티티를 생성하는 라이브러리라고 생각하면 편하다.

 

jpa

jpa는 코드 제너레이션을 활용하여 실제 쿼리를 작성하는데 사용되는 라이브러리다.

 

 

기본 설정은 모두 끝났고 쿼리 작성 후 실행도 잘 되는 것을 확인 했으니, 이제 본격적으로 공부를 시작할 수 있겠다.

 

 

참고: 김영한 실전! Query dsl