프로젝트/기록
[Spring] spring boot 3.x 에서 Querydsl 사용하기
공부하샘의 샘
2023. 3. 26. 00:23
1. 개요
Spring Boot 3.x에서 Querydsl을 사용하기 위한 세팅과 예제를 알아보겠습니다.
1.1. 개발 환경
IntelliJ IDEA Communication 2022.03.02
Java 17
Gradle 7.6.1
Spring Boot 3.0.4
2. 본론
2.1. 기본 환경 설정
2.1.1. build.gradle
// [number] Querydsl
// *********************
로 감싸져 있는 부분을 build.gradle에 추가하시면 됩니다.
이때 주의할 부분이 spring boot 3.x
부터는 특히나 jakarta
를 명시해줘야 합니다.
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.4'
id 'io.spring.dependency-management' version '1.1.0'
// [1] Querydsl
id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'
// ************
}
group = 'net'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
// [2] Querydsl
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
// ************
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.imgscalr:imgscalr-lib:4.2'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// [3] Querydsl
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
// QFile 생성 및 가져오기
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
// ************
}
test {
useJUnitPlatform()
}
// [4] 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
}
// ************
2.2. Test 환경 만들기
2.2.1. TestQueryDslConfig.java
src/test/java/net/<project name>/config/
에 파일을 추가해주세요.
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
@TestConfiguration
public class TestQueryDslConfig {
@PersistenceContext
private EntityManager em;
@Bean
public JPAQueryFactory queryFactory() {
return new JPAQueryFactory(em);
}
}
2.1.3. TestRepository.java
src/test/java/net/<project name>/repository/
Querydsl
테스트를 진행해보겠습니다.
package net.blogteamthreecoderhivebe.repository;
import com.querydsl.jpa.impl.JPAQueryFactory;
import net.blogteamthreecoderhivebe.config.TestJpaConfig;
import net.blogteamthreecoderhivebe.config.TestQueryDslConfig;
import net.blogteamthreecoderhivebe.entity.Job;
import net.blogteamthreecoderhivebe.entity.Member;
import net.blogteamthreecoderhivebe.entity.constant.MemberCareer;
import net.blogteamthreecoderhivebe.entity.constant.MemberLevel;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import java.util.Optional;
import static net.blogteamthreecoderhivebe.entity.QMember.member;
import static org.assertj.core.api.Assertions.assertThat;
@DisplayName("JPA 연결 테스트")
// Querydsl
@DataJpaTest
@Import(TestQueryDslConfig.class)
// ********
public class CoderHiveRepositoryTest {
@Autowired
private MemberRepository memberRepository;
@Autowired
private JobRepository jobRepository;
// Querydsl
@Autowired
private JPAQueryFactory queryFactory;
// ********
@DisplayName("QueryFactory 테스트")
@Test
public void QueryFactoryTest() {
final Job job = Job.builder()
.main("백엔드 개발")
.detail("웹 서버")
.build()
jobRepository.save(job);
String nickname = "고양이";
Job savedJob = jobRepository.findById((long)1).get();
Member mem = Member.builder()
.job(savedJob)
.email("example@coderhive.com")
.level(MemberLevel.BEGINNER)
.career(MemberCareer.ASSOCIATE)
.nickname(nickname)
.build();
memberRepository.save(mem);
// Querydsl
Member fetch = queryFactory.selectFrom(member)
.fetchOne();
// ********
assertThat(member.equals(mem));
}
}
2.3. main 에 세팅하기
2.3.1. QueryDslConfig.java
src/main/java/net/<project name>/config/
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QueryDslConfig {
@PersistenceContext
private EntityManager em;
@Bean
public JPAQueryFactory queryFactory() {
return new JPAQueryFactory(em);
}
}
2.3.2. PostRepositoryCustom.java
src/main/java/net/<project name>/repository/querydsl/
public interface PostRepositoryCustom {
List<Post> findAllInnerFetchJoin();
}
2.3.3. PostRepositoryCustomImpl.java
src/main/java/net/<project name>/repository/querydsl/
import com.querydsl.jpa.impl.JPAQueryFactory;
import static com.learning.jpa.domain.post.QPost.post;
import org.springframework.beans.factory.annotation.Autowired;
@Repository
public class PostCustomRepositoryImpl implements PostCustomRepository {
@Autowired
private JPAQueryFactory queryFactory;
@Override
public List<Post> findAllInnerFetchJoin() {
return queryFactory.selectFrom(post)
.innerJoin(post.comments)
.fetchJoin()
.fetch();
}
}
2.3.4. PostRepository.java
src/main/java/net/<project name>/repository/
public interface PostRepository extends JpaRepository<Post, Long>, PostRepositoryCustom{
...
}