[Java/JPA] QueryDSL์ด๋ž€?

2025. 3. 25. 16:31ยท๐Ÿ’ป Language/Java : ์ž๋ฐ”
728x90

QueryDSL

QueryDSL์€ Java ๊ธฐ๋ฐ˜์˜ ํƒ€์ž… ์•ˆ์ „(type-safe)ํ•œ SQL ์ฟผ๋ฆฌ ์ƒ์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ JPA, Hibernate ๋“ฑ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜์–ด ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ฝ”๋“œ๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค. ๋‹ค์Œ์€ QueryDSL์˜ ์ฃผ์š” ํŠน์ง•๊ณผ ์žฅ์ , ๊ทธ๋ฆฌ๊ณ  ์‚ฌ์šฉ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

 

QueryDSL์€ ์ •์  ํƒ€์ž…์„ ์ด์šฉํ•ด์„œ SQL๊ณผ ๊ฐ™์€ ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ฃผ๋Š” ์˜คํ”ˆ์†Œ์Šค ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค. Fluent API๋ฅผ ์ด์šฉํ•ด ์ฝ”๋“œ ์ž‘์„ฑ ํ˜•์‹์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.

 

QueryDSL์ด ์ ํ•ฉํ•œ ์ƒํ™ฉ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  1. ๋ณต์žกํ•œ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ (ex. ๊ฒŒ์‹œํŒ ํ•„ํ„ฐ, ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ)
  2. ๋™์  ์ฟผ๋ฆฌ๊ฐ€ ์ž์ฃผ ํ•„์š”ํ•œ ๋„๋ฉ”์ธ
  3. SQL ์ฟผ๋ฆฌ๋ฅผ ๋ฌธ์ž์—ด์ด ์•„๋‹Œ ์•ˆ์ „ํ•œ ์ฝ”๋“œ๋กœ ๋‹ค๋ฃจ๊ณ  ์‹ถ์„ ๋•Œ
 

Querydsl - Unified Queries for Java

Unified Queries for Java. Querydsl is compact, safe and easy to learn. <!-- Querydsl Unified Queries for Java Querydsl provides a unified querying layer for multiple backends in Java. Compared to the alternatives Querydsl is more compact, safer and easier

querydsl.com

 

QueryDSL์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

  1. ์ฟผ๋ฆฌ๋ฅผ Java ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ปดํŒŒ์ผ ์‹œ์ ์— ๋ฌธ๋ฒ• ์˜ค๋ฅ˜๋ฅผ ์žก์„ ์ˆ˜ ์žˆ๋‹ค.
    • SQL ๋ฌธ์ž์—ด ๊ธฐ๋ฐ˜ ์ฟผ๋ฆฌ(JPQL, Native Query)๋ณด๋‹ค ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๊ฐ€ ์ค„์–ด๋“œ๋Š” ์žฅ์ ์ด ์žˆ์Œ.
      → JPQL์€ ์ฟผ๋ฆฌ๋ฅผ ๋ฌธ์ž์—ด๋กœ ์ž‘์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ž˜๋ชป ์ž‘์„ฑํ•˜๊ฑฐ๋‚˜ ์˜คํƒ€๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋„ ์ปดํŒŒ์ผ ์‹œ์ ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋‹ค๊ฐ€ ๋Ÿฐํƒ€์ž„ ์ค‘์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹คํ–‰ ์ „์—๋Š” ์ž˜๋ชป๋œ ๋ถ€๋ถ„์„ ํŒŒ์•…ํ•  ์ˆ˜ ์—†๋‹ค.
  2. ๋™์  ์ฟผ๋ฆฌ ์ž‘์„ฑ์ด ์šฉ์ดํ•˜๋‹ค. (Qํด๋ž˜์Šค, ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ)
    • IF ์กฐ๊ฑด ๋“ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์œ ์—ฐํ•˜๊ฒŒ ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๋ณต์žกํ•œ ๊ฒ€์ƒ‰ ์กฐ๊ฑด(ex. ์—ฌ๋Ÿฌ ๊ฒ€์ƒ‰ ํ•„ํ„ฐ ์ ์šฉ)์— ์ ํ•ฉํ•˜๋‹ค.
      → JPQL์„ ์ด์šฉํ•ด ๋™์  ์ฟผ๋ฆฌ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฌธ์ž์—ด์„ ์กฐ๊ฑด์— ๋งž๊ฒŒ ์กฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ์ด ๊ฒฝ์šฐ ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์ง€๊ณ  ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค๋Š” ์น˜๋ช…์ ์ธ ๋‹จ์ ์ด ์กด์žฌํ•œ๋‹ค.
  3. IDE ์ž๋™์™„์„ฑ์„ ์ง€์›ํ•œ๋‹ค.
    • Qํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ํ•„๋“œ๋ช… ์ž๋™์™„์„ฑ์ด ๊ฐ€๋Šฅํ•˜์—ฌ ์ƒ์‚ฐ์„ฑ์ด ํ–ฅ์ƒ๋œ๋‹ค.
  4. SQL-Likeํ•œ ๋ฌธ๋ฒ•์„ Java ์ฝ”๋“œ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๊ธฐ์— ๋ฌธ๋ฒ•์ด ์ง๊ด€์ ์ด๋‹ค.

 

QueryDSL ์‚ฌ์šฉ ์˜ˆ์‹œ

1. Entity ํด๋ž˜์Šค

@Entity
public class Member {
    @Id @GeneratedValue
    private Long id;
    private String username;
    private int age;
}

 

2. Qํด๋ž˜์Šค ์ƒ์„ฑ

Gradle ๋˜๋Š” Maven์—์„œ annotationProcessor ์„ค์ •์œผ๋กœ Qํด๋ž˜์Šค(QMember) ์ž๋™ ์ƒ์„ฑ

 

Maven์˜ ๊ฒฝ์šฐ, IntelliJ ์šฐ์ธก ๋ฉ”์ด๋ธ ๋„๊ตฌ - Lifecycle - compile์„ ์‹คํ–‰ํ•˜์—ฌ Qํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

Maven - ํ”„๋กœ์ ํŠธ๋ช… - Lifecycle - compile
target - generated-sources - annotations ํ•˜์œ„

 

3-1. ์ •์  ์ฟผ๋ฆฌ ์˜ˆ์‹œ

JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
QMember member = QMember.member;

Member result = queryFactory
    .selectFrom(member)
    .where(member.username.eq("ํ™๊ธธ๋™"))
    .fetchOne();

 

3-2. ๋™์  ์ฟผ๋ฆฌ ์˜ˆ์‹œ

public List<Member> search(String usernameCond, Integer ageCond) {
    return queryFactory
        .selectFrom(member)
        .where(
            usernameEq(usernameCond),
            ageEq(ageCond)
        )
        .fetch();
}

private BooleanExpression usernameEq(String username) {
    return StringUtils.hasText(username) ? member.username.eq(username) : null;
}

private BooleanExpression ageEq(Integer age) {
    return age != null ? member.age.eq(age) : null;
}

 

 

QueryDSL ๋ฉ”์„œ๋“œ ์ข…๋ฅ˜

๋ชฉ์  ๋ฉ”์„œ๋“œ ์„ค๋ช…
SELECT select(), selectFrom() ์กฐํšŒํ•  ์ปฌ๋Ÿผ ๋˜๋Š” ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ง€์ •
FROM from() ์กฐํšŒํ•  ํ…Œ์ด๋ธ”(Qํƒ€์ž…)์„ ์ง€์ • (selectFrom์€ select + from ๊ฒฐํ•ฉ)
WHERE where() ์กฐ๊ฑด์ ˆ ์„ค์ • (BooleanExpression ๋„ฃ์Œ)
GROUP BY groupBy() ๊ทธ๋ฃนํ•‘
HAVING having() ๊ทธ๋ฃน ์กฐ๊ฑด
ORDER BY orderBy() ์ •๋ ฌ ์กฐ๊ฑด
JOIN join(), leftJoin(), rightJoin() ์กฐ์ธ (inner, left, right ๋“ฑ)
UPDATE update() ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ์ˆ˜์ • ์ฟผ๋ฆฌ
DELETE delete() ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ์‚ญ์ œ ์ฟผ๋ฆฌ
INSERT insert() SQLQueryFactory ์‚ฌ์šฉ ์‹œ ๊ฐ€๋Šฅ, JPA์—์„œ๋Š” ์ง์ ‘์ ์œผ๋กœ ์ง€์› X
FETCH fetch(), fetchOne(), fetchFirst(), fetchResults() ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜ ๋ฉ”์„œ๋“œ

 

WHERE ์กฐ๊ฑด์ ˆ ๋ฉ”์„œ๋“œ (BooleanExpression)

SQL ํ‘œํ˜„ QueryDSL ํ‘œํ˜„ ์„ค๋ช…
= eq() ๊ฐ™์Œ
!= ne() ๋‹ค๋ฆ„
> gt() ํฌ๋‹ค (greater than)
< lt() ์ž‘๋‹ค (less than)
>= goe() ํฌ๊ฑฐ๋‚˜ ๊ฐ™๋‹ค (greater or equal)
<= loe() ์ž‘๊ฑฐ๋‚˜ ๊ฐ™๋‹ค (less or equal)
IN (...) in() ํฌํ•จ๋จ
NOT IN (...) notIn() ํฌํ•จ๋˜์ง€ ์•Š์Œ
LIKE like(), contains(), startsWith() ๋ฌธ์ž์—ด ํฌํ•จ ์—ฌ๋ถ€
IS NULL isNull() null์ธ์ง€ ํ™•์ธ
IS NOT NULL isNotNull() null์ด ์•„๋‹Œ์ง€ ํ™•์ธ
AND, OR .and(), .or() ์กฐ๊ฑด ์กฐํ•ฉ
NOT .not() ๋ถ€์ • ์กฐ๊ฑด
BETWEEN A AND B between() ๋ฒ”์œ„ ์กฐ๊ฑด

 

์˜ˆ์‹œ ์ฝ”๋“œ

QMember member = QMember.member;

// SELECT * FROM member WHERE username = 'ํ™๊ธธ๋™'
queryFactory.selectFrom(member)
            .where(member.username.eq("ํ™๊ธธ๋™"))
            .fetch();

// WHERE age > 20 AND age < 30
queryFactory.selectFrom(member)
            .where(member.age.gt(20).and(member.age.lt(30)))
            .fetch();

// WHERE username IN ('a', 'b', 'c')
queryFactory.selectFrom(member)
            .where(member.username.in("a", "b", "c"))
            .fetch();

// WHERE age IS NOT NULL
queryFactory.selectFrom(member)
            .where(member.age.isNotNull())
            .fetch();
// UPDATE member SET username = '๋ณ€๊ฒฝ๋จ' WHERE age < 20
queryFactory.update(member)
            .set(member.username, "๋ณ€๊ฒฝ๋จ")
            .where(member.age.lt(20))
            .execute();

// DELETE FROM member WHERE age > 60
queryFactory.delete(member)
            .where(member.age.gt(60))
            .execute();
728x90
์ €์ž‘์žํ‘œ์‹œ ๋น„์˜๋ฆฌ ๋ณ€๊ฒฝ๊ธˆ์ง€ (์ƒˆ์ฐฝ์—ด๋ฆผ)

'๐Ÿ’ป Language > Java : ์ž๋ฐ”' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[E] java: warning: source release 17 requires target release 17  (0) 2025.04.17
[E] Unchecked cast: 'java.lang.Object' to 'java.util.Map<java.lang.String,java.lang.Object>'  (0) 2025.04.15
[Java] JDK ์„ค์น˜ (Windows 10, JDK 17)  (0) 2025.03.12
[Java] ๋ฐฑ์ค€ ์˜จ๋ผ์ธ ์ €์ง€ ๋‹จ๊ณ„๋ณ„๋กœ ํ’€์–ด๋ณด๊ธฐ - ์ž…์ถœ๋ ฅ๊ณผ ์‚ฌ์น™์—ฐ์‚ฐ  (0) 2024.11.20
[Java] ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ์ฃผ์š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ (1) - ๋ฒ„๋ธ”, ์„ ํƒ, ์‚ฝ์ž…, ์…€, ๋ณ‘ํ•ฉ, ํ€ต ์ •๋ ฌ  (0) 2024.11.19
'๐Ÿ’ป Language/Java : ์ž๋ฐ”' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [E] java: warning: source release 17 requires target release 17
  • [E] Unchecked cast: 'java.lang.Object' to 'java.util.Map<java.lang.String,java.lang.Object>'
  • [Java] JDK ์„ค์น˜ (Windows 10, JDK 17)
  • [Java] ๋ฐฑ์ค€ ์˜จ๋ผ์ธ ์ €์ง€ ๋‹จ๊ณ„๋ณ„๋กœ ํ’€์–ด๋ณด๊ธฐ - ์ž…์ถœ๋ ฅ๊ณผ ์‚ฌ์น™์—ฐ์‚ฐ
mxnxeonx
mxnxeonx
"์•„, ์ด๊ฑฐ ๋ญ์˜€๋”๋ผ"๋ฅผ ํ•˜์ง€ ์•Š๊ธฐ์œ„ํ•œ ์ผ๊ธฐ์žฅ.
  • mxnxeonx
    MJ's Development Diary
    mxnxeonx
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (158)
      • ๐Ÿ’ป Language (43)
        • Java : ์ž๋ฐ” (18)
        • Python : ํŒŒ์ด์ฌ (9)
        • ROS : ๋กœ๋ด‡์‹œ์Šคํ…œ (9)
        • Android : ์•ˆ๋“œ๋กœ์ด๋“œ (4)
        • JavaScript : ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ (2)
      • ๐ŸŒ Environment (19)
        • IDE : ํ†ตํ•ฉ๊ฐœ๋ฐœํ™˜๊ฒฝ (9)
        • Virtual : ๊ฐ€์ƒํ™˜๊ฒฝ (10)
      • โš™ Framework (12)
        • Vue-๋ทฐ (3)
        • Spring-์Šคํ”„๋ง (7)
      • ๐Ÿ’พ DataBase (18)
      • ๐ŸŒŒ OS (36)
        • Linux-๋ฆฌ๋ˆ…์Šค (36)
      • ๐Ÿ’ฌ CI · CD (7)
        • Git : ๊นƒ (7)
      • ๐Ÿ“ƒ ETC (6)
      • ๐Ÿค– AI (5)
  • ๋งํฌ

    • GitHub
  • ์ธ๊ธฐ ๊ธ€

  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.3
mxnxeonx
[Java/JPA] QueryDSL์ด๋ž€?
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”