QueryDSL

์ด๋ฏธ์—ฐยท2024๋…„ 8์›” 16์ผ

[spring]

๋ชฉ๋ก ๋ณด๊ธฐ
7/7

๐Ÿ”Ž QueryDSL

QueryDSL์€ ํƒ€์ž… ์•ˆ์ „ํ•œ SQL๊ณผ ์œ ์‚ฌํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ž๋ฐ” ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. JPA, MongoDB, SQL ๋“ฑ ๋‹ค์–‘ํ•œ ๋ฐฑ์—”๋“œ๋ฅผ ์ง€์›ํ•˜๋ฉฐ, ํŠนํžˆ JPA์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๐Ÿท๏ธ ํŠน์ง•

ํƒ€์ž… ์•ˆ์ „ํ•œ ์ฟผ๋ฆฌ ์ž‘์„ฑ
์ž๋™ ์™„์„ฑ ์ง€์›์œผ๋กœ ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ
๋™์  ์ฟผ๋ฆฌ ์ž‘์„ฑ ์šฉ์ด
๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ ORM ์ง€์›

๐Ÿ”Ž QueryDSL ์„ค์ •

QueryDSL์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ”„๋กœ์ ํŠธ์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ณ  Qํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-apt</artifactId>
    <version>${querydsl.version}</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-jpa</artifactId>
    <version>${querydsl.version}</version>
</dependency>

๐Ÿท๏ธ ํŠน์ง•

Maven ๋˜๋Š” Gradle์„ ํ†ตํ•œ ์˜์กด์„ฑ ๊ด€๋ฆฌ
APT(Annotation Processing Tool)๋ฅผ ์‚ฌ์šฉํ•œ Qํด๋ž˜์Šค ์ž๋™ ์ƒ์„ฑ
JPA ์—”ํ‹ฐํ‹ฐ ๊ธฐ๋ฐ˜์˜ ์ฟผ๋ฆฌ ๋„๋ฉ”์ธ ํด๋ž˜์Šค ์ƒ์„ฑ

๐Ÿ”Ž QueryDSL์„ ์‚ฌ์šฉํ•œ ์ฟผ๋ฆฌ ์ž‘์„ฑ

public List<User> findUsers(String username, Integer age) {
    QUser user = QUser.user;
    
    BooleanBuilder builder = new BooleanBuilder();
    if (StringUtils.hasText(username)) {
        builder.and(user.username.eq(username));
    }
    if (age != null) {
        builder.and(user.age.goe(age));
    }
    
    return queryFactory
        .selectFrom(user)
        .where(builder)
        .fetch();
}

๐Ÿท๏ธ ํŠน์ง•

ํƒ€์ž… ์•ˆ์ „ํ•œ ์ฟผ๋ฆฌ ์ž‘์„ฑ
๋ฉ”์„œ๋“œ ์ฒด์ด๋‹์„ ํ†ตํ•œ ์ง๊ด€์ ์ธ ์ฟผ๋ฆฌ ๊ตฌ์„ฑ
๋™์  ์ฟผ๋ฆฌ ์ž‘์„ฑ์ด ์šฉ์ด
์ปดํŒŒ์ผ ์‹œ์ ์— ์˜ค๋ฅ˜ ๊ฒ€์ถœ ๊ฐ€๋Šฅ

๐Ÿ”Ž QueryDSL์˜ ์žฅ๋‹จ์ 

๐Ÿท๏ธ ์žฅ์ 

ํƒ€์ž… ์•ˆ์ „์„ฑ ๋ณด์žฅ
IDE์˜ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ ํ™œ์šฉ ๊ฐ€๋Šฅ
๋™์  ์ฟผ๋ฆฌ ์ž‘์„ฑ์ด ํŽธ๋ฆฌ
๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋„ ์ž๋ฐ” ์ฝ”๋“œ๋กœ ์ž‘์„ฑ ๊ฐ€๋Šฅ

๐Ÿท๏ธ ๋‹จ์ 

ํ•™์Šต ๊ณก์„ ์ด ์กด์žฌ
ํ”„๋กœ์ ํŠธ ์„ค์ •์ด ๋‹ค์†Œ ๋ณต์žก
Qํด๋ž˜์Šค ์ƒ์„ฑ์œผ๋กœ ์ธํ•œ ๋นŒ๋“œ ์‹œ๊ฐ„ ์ฆ๊ฐ€

๐Ÿ”Ž ์ฃผ์˜์‚ฌํ•ญ

Qํด๋ž˜์Šค ๊ด€๋ฆฌ: ์ƒ์„ฑ๋œ Qํด๋ž˜์Šค๋ฅผ ๋ฒ„์ „ ๊ด€๋ฆฌ์— ํฌํ•จ์‹œํ‚ค์ง€ ์•Š๋„๋ก ์ฃผ์˜

gitignoreCopy/target/generated-sources/

ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ: fetchResults() ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ ์‹œ ์ฃผ์˜ ํ•„์š” (deprecate ์˜ˆ์ •)

QueryResults<User> results = queryFactory
    .selectFrom(user)
    .offset(pageable.getOffset())
    .limit(pageable.getPageSize())
    .fetchResults();

return new PageImpl<>(results.getResults(), pageable, results.getTotal());

์„ฑ๋Šฅ ์ตœ์ ํ™”: ํ•„์š”ํ•œ ์ปฌ๋Ÿผ๋งŒ ์กฐํšŒํ•˜๋Š” ํ”„๋กœ์ ์…˜ ์‚ฌ์šฉ

List<String> usernames = queryFactory
    .select(user.username)
    .from(user)
    .fetch();

ํ…Œ์ŠคํŠธ ์ž‘์„ฑ: QueryDSL ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ๋ฐ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ๊ถŒ์žฅ

JPQL๊ณผ์˜ ๋ณ‘ํ–‰ ์‚ฌ์šฉ: ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋Š” QueryDSL, ๊ฐ„๋‹จํ•œ ์ฟผ๋ฆฌ๋Š” JPQL ์‚ฌ์šฉ ๊ณ ๋ ค

0๊ฐœ์˜ ๋Œ“๊ธ€