TIL/Spring

๐Ÿ“š 3/14(๋ชฉ) ๋‚ด์ผ๋ฐฐ์›€์บ ํ”„ Java-Spring 55์ผ์ฐจ TIL - SpringData JPA QueryDSL

zzu_dev 2024. 3. 14. 22:00

๐Ÿ“  ์˜ค๋Š˜์˜ ํ•™์Šต ํ‚ค์›Œ๋“œ 

  • SpringData JPA - QueryDSL

 

 

 

 

๐Ÿ“ QueryDSL์ด๋ž€

  QueryDSL์€ ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ์ด๋‹ค. SQL์„ ์ง์ ‘ ๋ฌธ์ž์—ด๋กœ ์ž‘์„ฑํ•˜๋Š” ๋Œ€์‹ , QueryDSL์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. Maven์ด๋‚˜ Gradle๊ณผ ๊ฐ™์€ ์˜์กด์„ฑ ๊ด€๋ฆฌ ๋„๊ตฌ๋ฅผ ํ†ตํ•ด ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

- ํƒ€์ž… ์•ˆ์ •์„ฑ(Type Safety)
Java์˜ ํƒ€์ž… ์‹œ์Šคํ…œ์„ ํ™œ์šฉํ•˜์—ฌ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋ฏ€๋กœ ์˜คํƒ€๋‚˜ ์ž˜๋ชป๋œ ํ•„๋“œ๋ช…์„ ์‚ฌ์šฉํ•˜๋Š” ๋“ฑ์˜ ์‹ค์ˆ˜๋ฅผ ์ปดํŒŒ์ผ ์‹œ๊ฐ„์— ์žก์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

- ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ
SQL ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์ž๋ฐ” ์ฝ”๋“œ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋ฏ€๋กœ ๊ฐ€๋…์„ฑ์ด ํ–ฅ์ƒ๋˜๊ณ , ์ฝ”๋“œ์˜ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฌ์›Œ์ง„๋‹ค.

- ๋™์  ์ฟผ๋ฆฌ ์ž‘์„ฑ
๊ณ ์ •๋œ SQL๋ฌธ์ด ์•„๋‹Œ ์กฐ๊ฑด์— ๋งž๊ฒŒ ๋™์ ์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

- ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ
IDE์˜ ๋„์›€์„ ๋ฐ›์•„์„œ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์‚ฐ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

- ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ง€์›
๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ง€์›ํ•˜๋ฉฐ, JPA์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋  ๋•Œ๋Š” ํŠนํžˆ JPA ์—”ํ‹ฐํ‹ฐ์™€์˜ ํ†ตํ•ฉ์ด ์šฉ์ดํ•˜๋‹ค.

 

 

 

 

 

 

 

๐Ÿ“ QueryDSL ํ™˜๊ฒฝ์„ค์ • 

  QueryDSL์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์—”ํ‹ฐํ‹ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฟผ๋ฆฌ ํƒ€์ž…์ด๋ผ๋Š” ์ฟผ๋ฆฌ์šฉ ํด๋ž˜์Šค(Qclass)๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค. ํ™˜๊ฒฝ์„ค์ •์„ ํ†ตํ•ด QueryDSL์„ ์‚ฌ์šฉํ•ด ๋ณด์ž.

 

  • JPAQueryFactory ์˜์กด์„ฑ ์ฃผ์ž…

- build.gradleํŒŒ์ผ์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๋‹ค์‹œ build ํ•ด์ค€๋‹ค.

<build.gradleํŒŒ์ผ์— ์˜์กด์„ฑ ์ถ”๊ฐ€>

 

dependencies {
    .
    .
    .
    //QueryDSL ์ ์šฉ์„ ์œ„ํ•œ ์˜์กด์„ฑ (SpringBoot3.0.x๋ถ€ํ„ฐ๋Š” jakarta๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค)
    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"
}

 

 

 

  • Java ์ปดํŒŒ์ผ

- gradle -> other -> compile.java

<compileJava๋ฅผ ๋ˆŒ๋Ÿฌ์ค€๋‹ค>

 

 

 

  • Qclass ์ƒ์„ฑ ํ™•์ธ

- build -> generated -> sources -> annotationProcessor -> java -> main

<main ํŒจํ‚ค์ง€ ์•„๋ž˜์— Qclass๊ฐ€ ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค>

 

 

 

  • JPAConfig ํด๋ž˜์Šค ์ƒ์„ฑ

- @Configuration ์–ด๋…ธํ…Œ์ด์…˜ ์‚ฌ์šฉ

- ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด @PersistenceContext ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•ด EntityManager ๋นˆ์„ ์ฃผ์ž…

<JPAConfig ํด๋ž˜์Šค ์ƒ์„ฑ>

 

@Configuration
public class JPAConfig {

    @PersistenceContext
    private EntityManager em;

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

 

 

 

 

  • QueryRepository ์ƒ์„ฑ

- QEntity class๋ฅผ import ํ•˜๊ณ  ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

<QueryDSL์„ ์‚ฌ์šฉํ•˜๋Š” QueryRepository์™€ JPA๋ฅผ ์‚ฌ์šฉํ•˜๋Š” TodoRepository>

 

import static com.sparta.todoapp.entity.QTodo.todo;
.
.
.

@Repository
@RequiredArgsConstructor
public class QueryRepository {

    private final JPAQueryFactory jpaQueryFactory;

    public List<Todo> findByKeyword(String keyword) {

        return jpaQueryFactory
            .selectFrom(todo)
            .where(
                todo.title.contains(keyword)
                    .or(todo.content.contains(keyword))
                    .or(todo.user.username.contains(keyword))
            )
            .fetch();
    }
}