본문 바로가기
데이터 접근 기술

Kotlin, Querydsl 설정

by oncerun 2023. 7. 8.
반응형

 

목표

  • Spring Boot, kotlin, Gradle 7.x.x 환경에서 Querydsl을 사용하기 위한 설정을 진행한다.

 

* tip : 프로젝트의 gradle 버전은 project_root/gradle/wrapper/gradle-wrapper.properties에서 확인 가능하다

 

 

1. build.gradle Plugins 추가

 

plugins {
    id 'org.springframework.boot' version '2.6.8'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
    id 'org.jetbrains.kotlin.jvm' version '1.8.22'
    id 'org.jetbrains.kotlin.plugin.jpa' version '1.8.22'
    id 'org.jetbrains.kotlin.plugin.spring' version '1.8.22'
    id 'org.jetbrains.kotlin.kapt' version '1.8.22'
}

 

id 'org.jetbrains.kotlin.kapt'는 Gradle 플러그인을 설정하는 코드입니다.

 

이 코드는 Kotlin 언어와 관련된 기능인 Kotlin Annotation Processing Tool (KAPT)를 사용하기 위해 Gradle 프로젝트에 Kotlin Kapt 플러그인을 추가하는 것을 나타냅니다.

KAPT는 주로 안드로이드 앱 개발이나 Kotlin 기반 프로젝트에서 사용되며, 컴파일 시점에서 주석 처리된 코드를 생성하기 위해 사용됩니다. KAPT를 사용하면 주석 처리된 코드를 통해 자동으로 코드를 생성하거나 코드를 분석하는 등의 작업을 수행할 수 있습니다.

 

2. querydsl 의존성 추가.

 

2021년 7월 22일 5.0.0 버전이 출시되었습니다. 해당 릴리즈에서는 최소 Java 8을 대상으로 하며, Java 7을 사용하는 경우에는 최신 4.xx 버전을 사용해야 합니다. 

 

자세한 사항은 다음 릴리즈 노트를 확인하셔야 합니다.

http://querydsl.com/releases.html

 

Querydsl - Unified Queries for Java

 

querydsl.com

dependencies {
    implementation 'com.querydsl:querydsl-jpa:5.0.0'
    kapt('com.querydsl:querydsl-apt:5.0.0:jpa')
    kapt('org.springframework.boot:spring-boot-configuration-processor')
}

kapt('com.querydsl:querydsl-apt:5.0.0:jpa')는 Kotlin Kapt 플러그인을 사용하여 QueryDSL Annotation Processor를 프로젝트에 추가하는 코드입니다.  

위의 코드에서 `'com.querydsl:querydsl-apt:5.0.0:jpa'`는 QueryDSL Annotation Processor의 Maven coordinates(좌표)를 나타냅니다. Maven coordinates는 라이브러리를 고유하게 식별하는 데 사용되는 그룹 ID, 아티팩트 ID, 버전 및 선택적으로 패키지 타입으로 구성됩니다.

kapt('org.springframework.boot:spring-boot-configuration-processor')는 Kotlin Kapt 플러그인을 사용하여 Spring Boot Configuration Processor를 프로젝트에 추가하는 코드입니다.

Spring Boot Configuration Processor는 Spring Boot 프로젝트에서 설정 클래스에 대한 메타데이터를 생성하기 위해 사용되는 Annotation Processor입니다. '

 

이 프로세서는 @ConfigurationProperties 애노테이션이 지정된 클래스를 분석하여 해당 클래스의 프로퍼티에 대한 메타데이터를 생성하고, 이를 활용하여 구성 속성 값을 유효성 검사하고 설정할 수 있도록 도와줍니다.

더보기

Annotation Processor(주석 처리기)는 컴파일 시간에 소스 코드의 주석을 분석하고, 주석에 기반하여 추가적인 코드를 생성하거나 컴파일러 동작을 변경하는 도구입니다. 주로 Java 소스 코드에서 사용되며, 주석을 활용하여 코드 생성, 리소스 파일 생성, 유효성 검사, 코드 분석 등 다양한 작업을 수행할 수 있습니다.

Annotation Processor는 주석을 특정 애노테이션으로 지정하고, 해당 애노테이션이 붙은 요소(클래스, 메서드, 필드 등)를 식별합니다. 그런 다음, 주석에 대한 정보를 기반으로 처리 로직을 수행하고 필요한 코드를 생성합니다.

일반적으로 Annotation Processor는 다음과 같은 목적으로 사용됩니다:

1. 코드 생성: Annotation을 통해 컴파일 시간에 추가적인 코드를 생성합니다. 예를 들어, 데이터베이스 테이블과 연결되는 클래스에 대한 CRUD 기능을 자동으로 생성하는 등의 작업을 수행할 수 있습니다.

2. 리소스 파일 생성: Annotation을 기반으로 리소스 파일을 생성합니다. 예를 들어, REST API 문서를 자동으로 생성하는 등의 작업을 수행할 수 있습니다.

3. 유효성 검사: Annotation을 사용하여 코드의 유효성을 검사하고, 컴파일 시간에 오류를 감지할 수 있습니다. 예를 들어, 주석을 통해 입력값의 범위 검사, null 여부 검사 등을 수행할 수 있습니다.

4. 코드 분석: Annotation을 통해 코드를 분석하고, 특정 패턴이나 규칙을 확인하여 코드 품질을 개선하거나 특정 패턴을 적용하는 등의 작업을 수행할 수 있습니다.

Annotation Processor는 주로 프레임워크나 라이브러리에서 사용되며, 개발자가 컴파일 시간에 추가적인 작업을 자동화하고 반복 작업을 줄일 수 있도록 도와줍니다.

 

3. 개발 환경에서 생성된 Q 클래스를 사용할 수 있도록 generated 디렉토리를 sourceSet에 추가합니다.

 

sourceSets {
    main {
        kotlin {
            srcDirs = ["$projectDir/src/main/kotlin", "$projectDir/build/generated"]
        }
    }
}

위의 코드는 Gradle의 sourceSets 블록을 사용하여 프로젝트의 소스 디렉터리 구성을 설정하는 것입니다. 

sourceSets 블록은 Gradle에서 다양한 소스 세트를 정의하고, 해당 세트에 대한 구성을 지정하는 데 사용됩니다. 주로 소스 코드, 리소스, 테스트 코드 등을 구성하는 데 활용됩니다.

- srcDirs는 Kotlin 소스 파일이 위치하는 디렉토리의 배열을 지정합니다. "$projectDir/src/main/kotlin"은 프로젝트의 src/main/kotlin 디렉터리를 가리킵니다.
- build/generated은 빌드 프로세스에서 생성된 코드(예: Annotation Processor에 의해 생성된 코드)가 위치하는 디렉토리입니다. 따라서 해당 디렉터리를 Kotlin 소스 디렉터리에 추가함으로써 빌드 시 생성된 코드를 컴파일할 수 있게 됩니다.

 

4. 컴파일을 통한 Q클래스 생성 확인

 

build / generated /source / kapt / main / entity~에 Q 클래스 생성을 확인한다.

 

gradle 설정으로 소스 디렉토리에 생성된 Q 클래스 파일을 사용할 수 있게 되었을 것이다.

package com.group.libraryapp.domain.book;

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;


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

    private static final long serialVersionUID = -608098416L;

    public static final QBook book = new QBook("book");

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

    public final StringPath name = createString("name");

    public final EnumPath<BookType> type = createEnum("type", BookType.class);

    public QBook(String variable) {
        super(Book.class, forVariable(variable));
    }

    public QBook(Path<Book> path) {
        super(path.getType(), path.getMetadata());
    }

    public QBook(PathMetadata metadata) {
        super(Book.class, metadata);
    }

}

 

5. JPAQueryFactory 사용 방법

 

JPAQueryFactory는 QueryDSL 라이브러리에서 제공하는 클래스로 JPA를 사용하여 데이터베이스 쿼리를 작성하고 실행을 추상화한 클래스입니다.

 

이를 스프링이 관리하도록 할 것입니다.

@Configuration
class QuerydslConfig (
    private val em: EntityManager
){
    @Bean
    fun querydsl(): JPAQueryFactory {
        return JPAQueryFactory(em)
    }
}

 

특정 의문점이 드시는 분이 있을 것 같아 관련 레퍼런스를 가져왔습니다.

https://www.baeldung.com/hibernate-entitymanager

 

spring 기준으로 EntityManger를 자동으로 주입받는 경우는 단순한 EntityManager 대신 특수한 프록시를 주입해 줍니다.

 

Spring인 경우 SharedEntityManagerCreator 타입의 프록시 입니다.

 

주입된 EntityManager를 사용할 때마다 이 프록시는 기존의 EntityManager를 재사용하거나 새로운 EntityManager를 생성합니다. (커넥션 +1)

 

즉 어떤 경우에도 컨테이너는 각 EntityManager가 하나의 스레드에서 한정되도록 보장하기에 thread-safe 합니다.  

 

이 부분을 걱정하시는 분이 있을까 봐 찾아봤습니다.

 

 

 

여기까지 설정과 관련된 부분을 알아보았습니다. 

 

만약 Spring Data Jpa의 Repository의 기능과 QueryDSL을 동시에 사용하여 서로의 장점을 취할 땐 다음 레퍼런스가 도움이 될 것입니다.

 

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.single-repository-behavior

 

Spring Data JPA - Reference Documentation

Example 121. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del

docs.spring.io

 

반응형

'데이터 접근 기술' 카테고리의 다른 글

Querydsl Projections  (0) 2023.02.09
OneToOne 연관관계에 대한 고민.  (0) 2023.02.09
Querydsl 기본(3)  (0) 2023.02.07
Querydsl 기본(2)  (0) 2023.02.06
QueryDSL 적용 방법 알아보기.  (0) 2023.02.06

댓글