본문 바로가기
Spring/SpringBoot

[SpringBoot] Spring Boot 3 버전 이후 gradle에 querydsl 사용 환경 설정하기

by J4J 2024. 1. 22.
300x250
반응형

안녕하세요. J4J입니다.

 

이번 포스팅은 spring boot 3 버전 이후 gradle에 querydsl 사용 환경 설정하는 방법에 대해 적어보는 시간을 가져보려고 합니다.

 

 

 

관련 글

 

[SpringBoot] JPA에서 QueryDSL 사용하기

[SpringBoot] QueryDSL Projections로 결과값 핸들링하기

 

 

반응형

 

 

들어가기에 앞서

 

Spring Boot의 3버전이 등장하면서 최근에 생성되는 많은 프로젝트들은 3 버전 이상의 환경들을 구성하고는 합니다.

 

3 버전부터는 3 버전 이전과 설정하는 방법이 달라지기도 하고, 3 버전 이상의 환경에서 설정하는 방법을 더 궁금해하실 것 같아서 querydsl 사용 환경 설정하는 방법만 따로 정리하려고 합니다.

 

querydsl이 무엇인지에 대해 더 궁금하신 분들은 관련 글에 있는 링크들을 참고해주시면 됩니다.

 

 

 

 

gradle에서 querydsl 사용 환경 설정 방법

 

전체적인 흐름을 파악하기 쉽게 DB 테이블 생성부터 DB 설정 및 JPA 설정까지 모두 작성해 보겠습니다.

 

사용하는 DB는 mysql이니 참고 부탁드립니다.

 

 

 

[ 1. DB 테이블 생성 ]

 

create table student (
    no bigint auto_increment primary key,
    name varchar(200),
    age int,
    create_id varchar(50),
    create_at datetime,
    update_id varchar(50),
    update_at datetime
);

 

 

 

[ 2. properties 설정 ]

 

// application.yml
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver # DB driver
    url: jdbc:mysql://localhost:3306/querydsl?serverTimezone=UTC # DB url
    username: username # DB 계정 username
    password: password # DB 계정 password

  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQLDialect # 고유하게 사용할 DB dialect
        show_sql: true # console에 실행되는 sql 출력
        format_sql: true # sql 출력 시 보기 쉽게 format 수행

 

 

 

 

[ 3. build.gradle 설정 ]

 

// build.gradle
dependencies {
    // jpa
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

    // mysql
    runtimeOnly 'com.mysql:mysql-connector-j'

    // querydsl
    implementation "com.querydsl:querydsl-jpa:5.0.0:jakarta"
    annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
    annotationProcessor "jakarta.annotation:jakarta.annotation-api"
    annotationProcessor "jakarta.persistence:jakarta.persistence-api"
}

// querydsl generated 경로 설정
def querydslDir = "build/generated/querydsl"

tasks.withType(JavaCompile) {
    options.generatedSourceOutputDirectory = file(querydslDir)
}

clean {
    delete file(querydslDir)
}

 

 

 

[ 4. querydsl config 클래스 추가 ]

 

package com.jforj.querydsl.config;

import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@RequiredArgsConstructor
public class QuerydslConfig {

    private final EntityManager entityManager;

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

 

 

 

[ 5. DB entity 클래스 추가 ]

 

package com.jforj.querydsl.entity;

import jakarta.persistence.*;
import lombok.*;

import java.time.LocalDateTime;

@ToString
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(name = "student")
public class StudentEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long no;
    private String name;
    private int age;
    private String createId;
    private LocalDateTime createAt;
    private String updateId;
    private LocalDateTime updateAt;

    @Builder
    public StudentEntity(String name, int age, String createId, String updateId) {
        this.name = name;
        this.age = age;
        this.createId = createId;
        this.createAt = LocalDateTime.now();
        this.updateId = updateId;
        this.updateAt = LocalDateTime.now();
    }
}

 

 

 

 

[ 6. dto 클래스 추가 ]

 

package com.jforj.querydsl.dto;

import lombok.Getter;
import lombok.ToString;

@ToString
@Getter
public class StudentInfoDto {
    private String name;
    private int age;
}

 

 

 

[ 7. repository 클래스 추가 ]

 

// JPARepository
package com.jforj.querydsl.repository;

import com.jforj.querydsl.entity.StudentEntity;
import org.springframework.data.jpa.repository.JpaRepository;

public interface StudentJpaRepository extends JpaRepository<StudentEntity, Long> {

}


// Repostiory
package com.jforj.querydsl.repository;

import com.jforj.querydsl.dto.StudentInfoDto;
import com.jforj.querydsl.entity.StudentEntity;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.List;

import static com.jforj.querydsl.entity.QStudentEntity.studentEntity;

@Repository
@RequiredArgsConstructor
public class StudentRepository {

    private final JPAQueryFactory jpaQueryFactory;
    private final StudentJpaRepository studentJpaRepository;

    public void createStudent(String name, int age) {
        studentJpaRepository
                .save(
                        StudentEntity
                                .builder()
                                .name(name)
                                .age(age)
                                .createId("createId")
                                .updateId("updateId")
                                .build()
                );
    }

    public List<StudentInfoDto> selectStudentInfo() {
        return jpaQueryFactory
                .select(
                        Projections
                                .fields(
                                        StudentInfoDto.class,
                                        studentEntity.name,
                                        studentEntity.age
                                )
                )
                .from(studentEntity)
                .fetch();
    }
}

 

 

 

 

테스트

 

위와 같이 생성한 DB 구조에 맞게 설정을 모두 완료했다면 올바르게 동작하는지 테스트해보겠습니다.

 

다음과 같이 테스트 코드를 구성한 뒤 실행해 보면 올바르게 querydsl이 수행되는 것을 확인할 수 있습니다.

 

package com.jforj.querydsl.repository;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
@Slf4j
class StudentRepositoryTest {

    @Autowired
    private StudentRepository studentRepository;

    @Test
    void createStudent() {
        studentRepository.createStudent("test name", 100);
    }

    @Test
    void selectStudentInfo() {
        log.info(
                studentRepository.selectStudentInfo().toString()
        );
    }
}

 

student entity 생성 테스트

 

student info 조회 테스트

 

 

 

 

querydsl 실행 query parameter 확인하기

 

위의 설정에서 student entity를 생성하는 테스트를 수행해 보면 시스템 로그에 다음과 같이 실행된 query가 보이는 것을 확인할 수 있습니다.

 

student entity 생성 로그

 

 

 

해당 로그만 확인해 봤을 때 크게 문제 될 건 없어 보이지만 query가 동작되는 동안 필요한 parameter 정보들을 확인할 수 없는 불편함을 겪을 수 있습니다.

 

참고로 여기서 말하는 parameter 정보들은 위의 로그에서 "?"에 해당되는 값을 의미합니다.

 

 

 

 

해당 문제는 dependency를 추가하게 되면 쉽게 해결할 수 있습니다.

 

build.gradle에 다음과 같이 jpa 실행 로그를 parameter 정보까지 확인하도록 도와주는 의존성 추가를 해주겠습니다.

 

// build.gradle
dependencies {
    // querydsl log
    implementation "com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0"
}

 

 

 

의존성을 추가한 뒤 다시 동일한 테스트를 실행해 보겠습니다.

 

이전과 달리 parameter 정보가 매핑된 query를 명확히 확인하는 로그가 찍히는 것을 볼 수 있습니다.

 

student entity parameter 입력 로그

 

 

 

 

 

 

 

이상으로 spring boot 3 버전 이후 gradle에 querydsl 사용 환경 설정하는 방법에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

 

 

 

728x90
반응형

댓글