*책 내용과 다르게, 다음과 같은 환경에서 프로젝트 생성
- Windows11(윈도우 11) 환경
- 자바 JDK 17 버전 설치 https://yungenie.tistory.com/11
[Java] 차근차근 Java 설치하기 (JDK17, Window 11)
자바 개발 도구 설치 방법에 대해서 알아보겠습니다. Java17은 LTS(Long Term Support : 장기 지원) 릴리즈로 1년 후까지 기술 지원 및 버그를 개선한 서비스를 제공받을 수 있습니다. 업데이트 버전을 꾸
yungenie.tistory.com
- 스프링 부트 4.31.0 사용 - STS(Spring Tool Suite) 설치(Spring Tools for Eclipse - https://spring.io/tools)
=> https://priming.tistory.com/147 참고
[Windows] Spring Tool Suite 4(STS 4) 다운로드 및 설치
STS란?Spring Tool Suite(STS)는 스프링 프로젝트를 생성하고, 개발할 수 있게 해주는 도구입니다. STS 설치 과정에 대해 설명드리겠습니다. 설치 파일 다운로드STS 공식 사이트에서 설치 파일을 다운로
priming.tistory.com
- MySQL Community Server 8.0.42 설치 https://dev.mysql.com/downloads/mysql/
MySQL :: Download MySQL Community Server
Select Version: 9.3.0 Innovation 8.4.5 LTS 8.0.42 Select Operating System: Select Operating System… Microsoft Windows Ubuntu Linux Debian Linux SUSE Linux Enterprise Server Red Hat Enterprise Linux / Oracle Linux Fedora Linux - Generic Oracle Solaris mac
dev.mysql.com
- Gradle
**STS에서 Gradle 프로젝트 생성한 과정
*** 함께 보면 좋은 글
스프링 부트 핵심 가이드(장정우 지음) - 스프링 부트 개요
1. 스프링 프레임워크자바(Java) 기반 애플리케이션 프레임워크로, 엔터프라이즈급(기업 환경 대상 개발) 애플리케이션을 위한 다양한 기능 제공-> 오픈소스 경량급 애플리케이션 프레임워크로
keep-programming-study.tistory.com
스프링 부트 핵심 가이드(장정우 지음) - 개발에 앞서 알면 좋은 기초 지식
1. 서버 간 통신마이크로서비스 아키텍처에서 한 서버가 다른 서버에 통신을 요청하는 것을 의미-> 한 대는 서버/다른 한 대는 클라이언트가 됨 가장 많이 사용되는 방식은 HTTP/HTTPS 방식(TCP/IP, SOA
keep-programming-study.tistory.com
스프링 부트 핵심 가이드(장정우 지음) - Spring Data JPA 활용 1(JPQL, 쿼리 메서드 살펴보기, 정렬과
*책 내용과 다르게, 다음과 같은 환경에서 프로젝트 생성 Windows11(윈도우 11) 환경자바 JDK 17 버전 설치 https://yungenie.tistory.com/11 [Java] 차근차근 Java 설치하기 (JDK17, Window 11)자바 개발 도구 설치 방법
keep-programming-study.tistory.com
1. @Query 어노테이션 사용하기
- 직접 JPQL을 작성하여, JPA 구현체에서 자동으로 쿼리 문장을 해석하고 실행
- 어떤 데이터베이스를 선택했든 데이터베이스에 특화된 SQL을 작성할 수 있으며, 주로 튜닝된 쿼리 사용
@Query를 사용하여 ProductRepository.java에 메서드 작성
// Product 엔티티 중에서 name이 특정 값과 일치하는 것들을 찾아서 리스트로 반환
// :name은 JPQL 쿼리에서 사용하는 이름 기반 파라미터
// @Param("name")은 자바 메서드의 파라미터를 :name에 연결
@Query("SELECT FROM Product WHERE Product.name = :name")
List<Product> findByName(@Param("name") String name);
// 위의 findByName 메서드를 호출했을 때 나오는 하이버네이트 로그
Hibernate:
select
product0_.number as number1_0_,
product0_.created_at as created_2_0_,
product0_.name as name3_0_,
product0_.price as price4_0_,
product0_.stock as stock5_0_,
product0_.updated_at as updated_6_0_
from
product product0_
where
product0_.name=?
// Product 엔티티에서 엔티티 타입이 아닌, 원하는 특정 칼럼들만 추출
@Query("SELECT p.name, p.price, p.stock FROM Product p WHERE p.name = :name")
List<Object[]> findByName2(@Param("name") String name);
// 위의 findByName2 메서드를 호출했을 때 나오는 하이버네이트 로그
Hibernate:
select
product0_.name as col_0_0_,
product0_.price as col_1_0_,
product0_.stock as col_2_0_,
from
product product0_
where
product0_.name=?
2. QueryDSL 적용하기
1) QueryDSL의 특징
- 메서드 이름을 기반으로 생성하는 JPQL의 한계는 @Query 어노테이션을 통해 대부분 해소할 수 있지만,
직접 문자열을 입력하기 때문에 컴파일 시점에 에러를 잡지 못하고 런타임 에러가 발생할 수 있음
-> 이러한 문제를 해결하기 위해, 문자열이 아니라 코드로 쿼리를 작성하는 QueryDSL 사용 - 정적 타입을 통해 SQL과 같은 쿼리를 생성할 수 있도록 지원하는 프레임워크
- 문자열이나 XML 파일 대신, 자체 제공하는 플루언트(Fluent) API를 활용하여 쿼리 생성
QueryDSL의 장점
- IDE가 제공하는 코드 자동 완성 기능 사용 가능
- 문법적으로 잘못된 쿼리를 허용하지 않으므로, 정상적으로 작성된 QueryDSL은 문법 오류를 발생시키지 않음
- 고정된 SQL 쿼리를 작성하지 않으므로 동적으로 쿼리 생성 가능
- 코드로 작성하므로 가독성 및 생산성 향상
- 도메인 타입과 프로퍼티를 안전하게 참조할 수 있음
2) QueryDSL을 사용하기 위한 프로젝트 설정
- Gradle은 annotationProcessor라는 전용 configuration scope를 제공해서
별도의 APT 플러그인 없이도 annotation processing을 깔끔하게 처리할 수 있음
-> APT(Annotation Processing Tool)은 어노테이션으로 정의된 코드를 기반으로 새로운 코드를 생성하는 기능 - Maven과 Gradle에서 QueryDSL 사용 시 설정 차이
항목 | Maven | Gradle |
Annotation Processor 설정 | maven-compiler-plugin의 annotationProcessorPaths 사용 | annotationProcessor 의존성으로 설정 |
QueryDSL APT 설정 | querydsl-apt를 annotationProcessorPaths에 명시 | annotationProcessor 'com.querydsl:querydsl-apt:...' |
생성된 Q 클래스 경로 설정 | target/generated-sources/java 등으로 지정 | build/generated/querydsl 등으로 지정 |
소스 디렉토리 추가 | <sourceDirectory> 또는 IDE 설정 필요 | sourceSets.main.java.srcDirs += ... |
(1) build.gradle에 코드 추가
plugins {
... 생략 ...
// QueryDSL (JPA) 플러그인
id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'
}
.. 생략 ...
// QueryDSL 설정
def querydslDir = "$buildDir/generated/querydsl"
querydsl {
jpa = true
querydslSourcesDir = querydslDir
}
sourceSets {
main.java.srcDirs += querydslDir
}
compileJava {
options.annotationProcessorGeneratedSourcesDirectory = file(querydslDir)
}
dependencies {
... 생략 ...
// QueryDSL 관련 의존성
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta'
annotationProcessor 'jakarta.persistence:jakarta.persistence-api:3.1.0'
}
(2) build.gradle 우클릭 후 Gradle -> Refresh Gradle Project 클릭
3) 기본적인 QueryDSL 사용
(1) STS에서 Q클래스 인식이 안되는 문제
- STS는 build/generated/querydsl 디렉토리를 자동으로 소스 디렉토리로 인식하지 않으므로 수동으로 추가
- STS에서 프로젝트 우클릭 → Properties 클릭
- Properties 창에서 Java Build Path → Source 탭으로 이동
- Add Folder 클릭
- build/generated/querydsl 선택
- Apply and Close
- 그래도 안 되면?
- STS 재시작
- Project > Clean 실행
- Gradle > Refresh Gradle Project 실행
(2) 테스트 코드 새로 작성 중 QProduct가 import가 안되는 문제... cmd에서 gradlew clean build 하는것조차안됨
-> gradlew clean build 후에 gradlew compileQuerydsl가 되어야함...
- compileQuerydsl 태스크가 Spring, Jakarta, Lombok 등 거의 모든 의존성을 못 찾고 있음
-> 즉, compileQuerydsl이 실행될 때 필요한 클래스 경로(classpath)가 제대로 설정되지 않은 상태.. 해결을 위해 여러가지 시도- QueryDSL 추가 시 gradlew clean build가 안되는문제 해결해야함!!
C:\sts\workspace\study>gradlew clean build
> Task :compileQuerydsl FAILED
...
* What went wrong:
Execution failed for task ':compileQuerydsl'.
> Compilation failed; see the compiler output below.
C:\sts\workspace\study\src\main\java\com\example\demo\service\impl\ProductServiceImpl.java:22: error: cannot find symbol
private final Logger LOGGER = LoggerFactory.getLogger(ProductServiceImpl.class);
symbol: class Logger
location: class ProductServiceImpl
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\dao\impl\ProductDAOImpl.java:28: error: cannot find symbol
@Autowired
^
symbol: class Autowired
location: class ProductDAOImpl
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:40: error: cannot find symbol
@Id
^
symbol: class Id
location: class Product
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:45: error: cannot find symbol
@GeneratedValue(strategy = GenerationType.IDENTITY)
^
symbol: class GeneratedValue
location: class Product
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:45: error: cannot find symbol
@GeneratedValue(strategy = GenerationType.IDENTITY)
^
symbol: variable GenerationType
location: class Product
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:50: error: cannot find symbol
@Column(nullable = false)
^
symbol: class Column
location: class Product
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:54: error: cannot find symbol
@Column(nullable = false)
^
symbol: class Column
location: class Product
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:58: error: cannot find symbol
@Column(nullable = false)
^
symbol: class Column
location: class Product
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\dto\ProductDTO.java:8: error: cannot find symbol
@JsonProperty("name")
^
symbol: class JsonProperty
location: class ProductDTO
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\dto\ProductDTO.java:11: error: cannot find symbol
@JsonProperty("price")
^
symbol: class JsonProperty
location: class ProductDTO
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\dto\ProductDTO.java:14: error: cannot find symbol
@JsonProperty("stock")
^
symbol: class JsonProperty
location: class ProductDTO
C:\sts\workspace\study\src\main\java\com\example\demo\service\impl\ProductServiceImpl.java:29: error: cannot find symbol
@Autowired
^
symbol: class Autowired
location: class ProductServiceImpl
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\dao\impl\ProductDAOImpl.java:19: error: cannot find symbol
@Component // Spring이 이 클래스를 Bean으로 등록할 수 있도록 지정
^
symbol: class Component
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\repository\ProductRepository.java:7: error: cannot find symbol
public interface ProductRepository extends JpaRepository<Product, Long> {
^
symbol: class JpaRepository
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:21: error: cannot find symbol
@Getter
^
symbol: class Getter
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:23: error: cannot find symbol
@Setter
^
symbol: class Setter
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:25: error: cannot find symbol
@NoArgsConstructor
^
symbol: class NoArgsConstructor
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:27: error: cannot find symbol
@AllArgsConstructor
^
symbol: class AllArgsConstructor
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:29: error: cannot find symbol
@Entity
^
symbol: class Entity
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:31: error: cannot find symbol
@Builder
^
symbol: class Builder
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:33: error: cannot find symbol
@EqualsAndHashCode
^
symbol: class EqualsAndHashCode
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:35: error: cannot find symbol
@ToString(exclude="name")
^
symbol: class ToString
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:37: error: cannot find symbol
@Table(name="product")
^
symbol: class Table
C:\sts\workspace\study\src\main\java\com\example\demo\service\impl\ProductServiceImpl.java:19: error: cannot find symbol
@Service
^
symbol: class Service
C:\sts\workspace\study\src\main\java\com\example\demo\StudyApplication.java:6: error: cannot find symbol
@SpringBootApplication
^
symbol: class SpringBootApplication
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\dao\impl\ProductDAOImpl.java:7: error: package org.springframework.beans.factory.annotation does not exist
import org.springframework.beans.factory.annotation.Autowired;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\dao\impl\ProductDAOImpl.java:8: error: package org.springframework.stereotype does not exist
import org.springframework.stereotype.Component;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\repository\ProductRepository.java:3: error: package org.springframework.data.jpa.repository does not exist
import org.springframework.data.jpa.repository.JpaRepository;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:6: error: package jakarta.persistence does not exist
import jakarta.persistence.Column;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:7: error: package jakarta.persistence does not exist
import jakarta.persistence.Entity;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:8: error: package jakarta.persistence does not exist
import jakarta.persistence.GeneratedValue;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:9: error: package jakarta.persistence does not exist
import jakarta.persistence.GenerationType;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:10: error: package jakarta.persistence does not exist
import jakarta.persistence.Id;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:11: error: package jakarta.persistence does not exist
import jakarta.persistence.Table;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:12: error: package lombok does not exist
import lombok.AllArgsConstructor;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:13: error: package lombok does not exist
import lombok.Builder;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:14: error: package lombok does not exist
import lombok.EqualsAndHashCode;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:15: error: package lombok does not exist
import lombok.Getter;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:16: error: package lombok does not exist
import lombok.NoArgsConstructor;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:17: error: package lombok does not exist
import lombok.Setter;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\entity\Product.java:18: error: package lombok does not exist
import lombok.ToString;
^
C:\sts\workspace\study\src\main\java\com\example\demo\jpa\data\dto\ProductDTO.java:4: error: package com.fasterxml.jackson.annotation does not exist
import com.fasterxml.jackson.annotation.JsonProperty;
^
C:\sts\workspace\study\src\main\java\com\example\demo\service\impl\ProductServiceImpl.java:4: error: package org.slf4j does not exist
import org.slf4j.Logger;
^
C:\sts\workspace\study\src\main\java\com\example\demo\service\impl\ProductServiceImpl.java:5: error: package org.slf4j does not exist
import org.slf4j.LoggerFactory;
^
C:\sts\workspace\study\src\main\java\com\example\demo\service\impl\ProductServiceImpl.java:6: error: package org.springframework.beans.factory.annotation does not exist
import org.springframework.beans.factory.annotation.Autowired;
^
C:\sts\workspace\study\src\main\java\com\example\demo\service\impl\ProductServiceImpl.java:7: error: package org.springframework.stereotype does not exist
import org.springframework.stereotype.Service;
^
C:\sts\workspace\study\src\main\java\com\example\demo\StudyApplication.java:3: error: package org.springframework.boot does not exist
import org.springframework.boot.SpringApplication;
^
C:\sts\workspace\study\src\main\java\com\example\demo\StudyApplication.java:4: error: package org.springframework.boot.autoconfigure does not exist
import org.springframework.boot.autoconfigure.SpringBootApplication;
^
48 errors
...
- GetController.java, ProductController.java 주석 처리
-
gradlew --version으로 gradle 버전 확인: 8.5 이상이 필요하다고 하는데 8.14버전이었음...
-> 찾아보니 8.14버전이 8.5버전보다 높은 게 맞음...
- gradlew --refresh-dependencies clean build --info 시도: 캐시 초기화 후 모든 의존성을 다시 다운로드한 후 로그출력
-> 실패 이유가 안 나옴
- build.gradle 코드 전체 리팩토링
-> 또다른 문제 발생...
plugins {
id 'java'
id 'org.springframework.boot' version '3.5.3'
id 'io.spring.dependency-management' version '1.1.7'
id 'jacoco'
id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
repositories {
mavenCentral()
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
dependencies {
// Spring Boot
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// DB
runtimeOnly 'com.mysql:mysql-connector-j'
testImplementation 'com.h2database:h2'
// JSON
implementation 'com.google.code.gson:gson:2.10.1'
// Swagger / OpenAPI
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.9'
implementation 'io.swagger.core.v3:swagger-annotations:2.2.20'
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// Spring Configuration Processor
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
// QueryDSL
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta'
annotationProcessor 'jakarta.persistence:jakarta.persistence-api:3.1.0'
// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.assertj:assertj-core:3.24.2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
// JaCoCo API (optional)
implementation 'org.jacoco:org.jacoco.core:0.8.10'
// SLF4J
implementation 'org.slf4j:slf4j-api:2.0.12'
implementation 'org.slf4j:slf4j-simple:2.0.12'
}
tasks.withType(JavaCompile) {
options.compilerArgs << "-parameters"
}
tasks.named('test') {
useJUnitPlatform()
}
jacocoTestReport {
reports {
html.required = true
}
}
// QueryDSL 설정
def querydslDir = "$buildDir/generated/querydsl"
tasks.named('compileQuerydsl', JavaCompile) {
source = sourceSets.main.java
classpath = sourceSets.main.compileClasspath
destinationDirectory.set(file(querydslDir))
options.annotationProcessorGeneratedSourcesDirectory = file(querydslDir)
options.compilerArgs += ["-proc:only"]
options.annotationProcessorPath = files(configurations.annotationProcessor)
}
sourceSets {
main.java.srcDirs += querydslDir
}
- 네이버 블로그 코드를 보고 build.gradle 전체 리팩토링.. 드디어성공함 ㅠㅠㅠㅠㅠㅠ
https://blog.naver.com/2001200190/223934440513
JPA,QueryDSL5 실행 예제로(인텔리제이와 STS에서 모두 가능한 설정) 다른 블로그에서 잘안되시는 분
많은 블로그 글에서 실행보니 버전문제등으로 잘안되는 부분이 많아서 실제로 해보면서 정리해봤습니다. 사...
blog.naver.com
buildscript { //
ext {
queryDslVersion = "5.0.0"
}
dependencies { // 여기가 없으면 STS에서는 gradle tasks option 항목이 없어 queryDSL 컴파일이 안됨
classpath("gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.10")
}
}
plugins {
id 'java'
id 'org.springframework.boot' version '3.5.3'
id 'io.spring.dependency-management' version '1.1.7'
id 'jacoco'
id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
repositories {
mavenCentral()
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
dependencies {
// Spring Boot
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// DB
runtimeOnly 'com.mysql:mysql-connector-j'
testImplementation 'com.h2database:h2'
// JSON
implementation 'com.google.code.gson:gson:2.10.1'
// Swagger / OpenAPI
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.9'
implementation 'io.swagger.core.v3:swagger-annotations:2.2.20'
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// Spring Configuration Processor
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
// QueryDSL
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta'
annotationProcessor 'jakarta.persistence:jakarta.persistence-api:3.1.0'
// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.assertj:assertj-core:3.24.2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
// JaCoCo API (optional)
implementation 'org.jacoco:org.jacoco.core:0.8.10'
// SLF4J
implementation 'org.slf4j:slf4j-api:2.0.12'
implementation 'org.slf4j:slf4j-simple:2.0.12'
// H2 데이터베이스 (테스트용 인메모리 DB)
runtimeOnly 'com.h2database:h2'
}
tasks.withType(JavaCompile) {
options.compilerArgs << "-parameters"
}
tasks.named('test') {
useJUnitPlatform()
}
jacocoTestReport {
reports {
html.required = true
}
}
// QueryDSL 설정
def querydslDir = "$buildDir/generated/querydsl"
tasks.withType(JavaCompile) {
options.generatedSourceOutputDirectory = file(querydslDir)
}
querydsl {
jpa = true
querydslSourcesDir = querydslDir
}
sourceSets { //
main.java.srcDir querydslDir
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
querydsl.extendsFrom compileClasspath
}
compileQuerydsl {
options.annotationProcessorPath = configurations.querydsl
}
clean {
delete file(querydslDir)
}
(3) 테스트 코드 새로 작성 (ProductRepositoryTest.java)
// src/test/java/com.example.demo/ProductRepositoryTest.java
package com.example.demo;
//Java의 List 클래스 import
import java.util.List;
//JUnit 5의 테스트 어노테이션
import org.junit.jupiter.api.Test;
//Spring Boot의 JPA 테스트용 어노테이션
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
//QueryDSL의 JPAQuery 클래스 import
import com.querydsl.jpa.impl.JPAQuery;
//테스트 대상 엔티티 및 리포지토리 import
import com.example.demo.jpa.data.entity.Product;
import com.example.demo.jpa.data.entity.QProduct;
//JPA의 EntityManager 관련 클래스 import
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
//JPA 관련 테스트를 위한 설정. 실제 DB 대신 테스트용 인메모리 DB(H2 등)를 사용함
@DataJpaTest
public class ProductRepositoryTest {
// EntityManager를 주입받아 QueryDSL에서 사용
@PersistenceContext
EntityManager entityManager;
// QueryDSL을 활용한 테스트 메서드
@Test
void queryDslTest() {
// QueryDSL의 JPA 기반 쿼리 객체 생성
JPAQuery<Product> query = new JPAQuery<>(entityManager);
// QProduct는 QueryDSL이 자동 생성해주는 클래스 (Product 엔티티에 대한 메타 정보 포함)
QProduct qProduct = QProduct.product;
// QueryDSL을 사용하여 name이 "펜"인 Product를 가격 오름차순으로 조회
List<Product> productList = query
.from(qProduct) // 조회 대상 테이블 지정
.where(qProduct.name.eq("펜")) // 조건: name이 "펜"인 경우
.orderBy(qProduct.price.asc()) // 가격 오름차순 정렬
.fetch(); // 결과 리스트로 반환
// 조회된 결과 출력
for (Product product : productList) {
System.out.println("--------------");
System.out.println();
System.out.println("Product Number: " + product.getNumber()); // 제품 번호
System.out.println("Product Name: " + product.getName()); // 제품 이름
System.out.println("Product Price: " + product.getPrice()); // 제품 가격
System.out.println("Product Stock: " + product.getStock()); // 제품 재고
System.out.println();
System.out.println("--------------");
}
}
}
(4) src/test/resources에 application.properties 새로 생성(테스트 전용 설정으로 분리)
# 테스트용 인메모리 H2 DB 설정
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
# JPA 설정
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
# H2 콘솔 (선택)
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
- 또다시 엄청난 문제들이 발생....(해결은 다음 글에 이어서)
'스프링(Spring), 스프링부트(SpringBoot) > 스프링부트(SpringBoot) 기초' 카테고리의 다른 글
스프링 부트 핵심 가이드(장정우 지음) - Spring Data JPA 활용 1(JPQL, 쿼리 메서드 살펴보기, 정렬과 페이징 처리) (0) | 2025.08.15 |
---|---|
스프링 부트 핵심 가이드(장정우 지음) - JaCoCo를 활용한 테스트 커버리지 확인, 테스트 주도 개발(TDD) (0) | 2025.08.12 |
스프링 부트 핵심 가이드(장정우 지음) - 테스트 코드 작성하기2 (0) | 2025.08.08 |
스프링 부트 핵심 가이드(장정우 지음) - 테스트 코드 작성하기 (0) | 2025.07.30 |
스프링 부트 핵심 가이드(장정우 지음) - 데이터베이스 연동 4: 서비스와 컨트롤러 설계2, 롬복(Lombok) (0) | 2025.07.24 |