starter 설정
gradle 설정
build.gradle > dependencies에 다음을 추가한다.
// querydsl setting
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"
추가된 build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.3'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.futuregoing'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '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'
// querydsl setting
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')
}
application.yml 설정
spring:
datasource:
url: jdbc:mysql://주소:3306/spring_lecture?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
username: 아이디
password: 비밀번호
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: create
show-sql: true
open-in-view: false
properties:
hibernate:
format_sql: true
# show_sql: true
highlight_sql: true
logging:
level:
org.hibernate.sql: debug
spring.jpa.hibernate.ddl-auto: create
애플리케이션 실행 시점에 테이블을 drop 하고 다시 create한다.
spring.jpa.properties.hibernate.show_sql: true
System.out에 하이버네이트 실행 SQL을 남긴다.
loggin.level.org.hibernate.sql: debug
logger를 통해 하이버네이트 실행 SQL을 남긴다. (debug level)
스프링부트 3 설정 주의사항
1. Java 17 이상 사용
2. javax 대신 jakarta 패키지 사용
3. 빌드시 IntelliJ IDEA가 아니라 Gradle을 선택
테스트 Entity 생성
package com.futuregoing.lecturequerydsl;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Getter;
@Entity
@Getter
public class HelloEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
IDENTITY 전략은 데이터베이스의 auto increment 기능을 이용하여 엔티티의 primary key 값을 자동으로 생성한다.
Entity 기반으로 Q타입 생성
1. Gradle > Tasks > build > clean
2. Gradle > Tasks > other > compileJava
build 폴더에 Q타입이 생성된 것을 확인할 수 있다.
QHelloEntity
@Generated("com.querydsl.codegen.DefaultEntitySerializer")
public class QHelloEntity extends EntityPathBase<HelloEntity> {
private static final long serialVersionUID = 1306507894L;
public static final QHelloEntity helloEntity = new QHelloEntity("helloEntity");
public final NumberPath<Long> id = createNumber("id", Long.class);
public QHelloEntity(String variable) {
super(HelloEntity.class, forVariable(variable));
}
public QHelloEntity(Path<? extends HelloEntity> path) {
super(path.getType(), path.getMetadata());
}
public QHelloEntity(PathMetadata metadata) {
super(HelloEntity.class, metadata);
}
}
Q타입 이란?
1. querydsl을 사용하여 타입 안전한 쿼리를 생성할 때 사용되는 클래스이다.
2. Q타입 클래스는 엔티티 클래스에 해당하는 메타 모델을 표현한다.
3. 이 메타 모델을 사용하여 SQL 또는 JPQL 쿼리를 타입 안전 방식으로 구성할 수 있다.
4. 컴파일 타임에 쿼리의 올바름을 검증할 수 있어, 런타임 시 발생할 수 있는 오류를 미리 방지할 수 있다.
5. 개발 환경에서 Q타입을 사용하면 필드 이름과 메서드를 자동으로 완성할 수 있어, 개발 효율성을 높일 수 있다.
6. Q타입을 사용하면 복잡한 조건을 가진 동적 쿼리를 보다 쉽게 구성할 수 있다.
테스트 코드로 Q타입 동작 확인
package com.futuregoing.lecturequerydsl;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
@Transactional
class LectureQuerydslApplicationTests {
@Autowired
EntityManager em;
@Test
void contextLoads() {
HelloEntity helloEntity = new HelloEntity();
em.persist(helloEntity);
JPAQueryFactory query = new JPAQueryFactory(em);
QHelloEntity qHelloEntity = QHelloEntity.helloEntity;
HelloEntity result = query.selectFrom(qHelloEntity)
.fetchOne();
Assertions.assertThat(result).isEqualTo(helloEntity);
Assertions.assertThat(result.getId()).isEqualTo(helloEntity.getId());
}
}