기존 스프링부트 2.x에서 QueryDSL 설정은 아래와 같다.
build.gradle
// queryDSL version 정보
buildscript {
ext {
queryDslVersion = "5.0.0"
}
}
plugins {
id 'org.springframework.boot' version '2.6.5'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10' // queryDSL plugins 추가
id 'java'
}
group = 'com.springboot2'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
/* queryDSL */
implementation "com.querydsl:querydsl-jpa:${queryDslVersion}"
implementation "com.querydsl:querydsl-apt:${queryDslVersion}"
implementation "com.querydsl:querydsl-core:${queryDslVersion}"
}
tasks.named('test') {
useJUnitPlatform()
}
/* queryDSL 빌드 설정 추가 */
// queryDSL에서 사용할 경로 설정
def querydslDir = "$buildDir/generated/querydsl"
// JPA 사용 여부와 사용할 경로를 설정
querydsl {
jpa = true
querydslSourcesDir = querydslDir
}
// build 시 사용할 sourceSet 추가
sourceSets {
main.java.srcDir querydslDir
}
// queryDSL 컴파일 시 사용할 옵션 설정
compileQuerydsl {
options.annotationProcessorPath = configurations.querydsl
}
// queryDSL이 compileClassPath를 상속하도록 설정
configurations {
compileOnly {
extendsFrom annotationProcessor
}
querydsl.extendsFrom compileClasspath
}
/* 빌드 시 테스트 제외 */
test {
exclude '**/*'
}
설정 후 JPAQueryFactory 생성 시 EntityManager를 넣어주도록 @Bean을 주입한다.
package com.springboot2.legacy.config;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManager;
@Configuration
public class JpaConfig {
@Bean
JPAQueryFactory jpaQueryFactory(EntityManager em) {
return new JPAQueryFactory(em);
}
}
이후 JPAQueryFactory를 통해 로직을 구성하면 된다.
package com.springboot2.legacy.service.first;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.springboot2.legacy.entity.first.PokemonEntity;
import com.springboot2.legacy.entity.first.QPokemonEntity;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class PokemonService {
private final JPAQueryFactory queryFactory;
public List<PokemonEntity> selectPokemon() {
return queryFactory
.selectFrom(QPokemonEntity.pokemonEntity)
.fetch();
}
}
테스트 후 정상 동작 확인
@Autowired
PokemonService pokemonService;
@Test
void firstDB() {
List<PokemonEntity> pokemonEntities = pokemonService.selectPokemon();
pokemonEntities.forEach(ent -> System.out.println("FIRST DB QueryDSL : " + ent.getPokemonId() + " : " + ent.getName()));
}
이 설정은 스프링 부트 3.x 버전에선 변경해야 한다.
해당 변경 사항은 오라클이 JavaEE를 이클립스 재단으로 넘기면서 기존 패키지명이 javax -> jakarta로 변경된 것과 관련있다. 이에 QueryDSL 라이브러리도 jakarta에 맞추어 변경된 것으로 보인다.
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.2'
id 'io.spring.dependency-management' version '1.1.2'
/* 해당 플러그인이 부트3에서는 에러가 남 ( Attempt to recreate a file for type ~ ) */
// id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'
}
group = 'com.springboot3'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
// queryDSL이 compileClassPath를 상속하도록 설정
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
/* 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()
}
/* queryDSL 설정 추가 */
/* 부트3에서는 Entity를 수정한 후, run을 하면 자동으로 QClass가 생성된다. */
// queryDSL에서 사용할 경로 설정
def querydslDir = "$buildDir/generated/querydsl"
sourceSets {
main.java.srcDirs += [ querydslDir ]
}
tasks.withType(JavaCompile) {
options.generatedSourceOutputDirectory = file(querydslDir)
}
clean.doLast {
file(querydslDir).deleteDir()
}
/* 빌드 시 테스트 제외 */
test {
exclude '**/*'
}
기존에는 querydsl plugin을 통하여 QType Class를 생성하였으나, 이제는 해당 플러그인이 없어도 알아서 QType Class를 생성한다.
때문에 querydsl plugin을 사용하게되면 QType Class가 두 번 생성되면서 에러가 발생하게 된다.
[ERROR] Attempt to recreate a file for type com.springboot3.db.entity.first.QPokemonEntity
[ERROR] Attempt to recreate a file for type com.springboot3.db.entity.second.QItemEntity
jakarta.annotation-api와 jakarta.persistence-api을 추가하지 않을 경우, 아래와 같은 에러가 발생하게 된다.
java.lang.NoClassDefFoundError:javax/persistence/Entity
동일하게 테스트 후 정상 동작하는지 확인하면 끝 😉
FIRST DB QueryDSL : 121 : Pikachu
FIRST DB QueryDSL : 122 : Bulbasaur
FIRST DB QueryDSL : 123 : Charmander
FIRST DB QueryDSL : 124 : Squirtle
FIRST DB QueryDSL : 125 : Butterfree
FIRST DB QueryDSL : 126 : Rattata
FIRST DB QueryDSL : 127 : Clefairy
FIRST DB QueryDSL : 128 : Arbok
FIRST DB QueryDSL : 129 : Diglett
FIRST DB QueryDSL : 130 : Kadabra
참고
https://post.dooray.io/we-dooray/tech-insight-ko/back-end/4173/
'좌충우돌 개발기! > DB 설정' 카테고리의 다른 글
[Spring Boot] (6)스프링부트 2.x / 3.x 에서 DB 사용 예제 (0) | 2023.08.24 |
---|---|
[Spring Boot] (5)다중 DB 환경에서 QueryDSL 사용하기 (0) | 2023.08.24 |
[Spring Boot] (3) MyBatis 3에서의 DB 설정 (0) | 2023.08.22 |
[Spring Boot] (2) MyBatis 셋팅 변경 (1) | 2023.08.21 |
[Spring Boot] (1) DB 사용을 위한 셋팅 구성 (0) | 2023.08.20 |