๊ณต๋ถ€/TIL

[20250214] querydsl ๊ธฐ๋ณธ ์˜ˆ์‹œ๋กœ ์‚ฌ์šฉ๋ฐฉ๋ฒ• ์•Œ์•„๋ณด๊ธฐ!

dvlpsy๐ŸŒผ 2025. 2. 14. 16:37
๋ฐ˜์‘ํ˜•

Querydsl ์™„์ „ ์ •๋ณต ๊ฐ€์ด๋“œ: ์ดˆ๋ณด์ž๋„ ์ดํ•ดํ•˜๋Š” ํ•ต์‹ฌ ๊ฐœ๋…๊ณผ ํ™œ์šฉ๋ฒ•

Querydsl์€ ๋ณต์žกํ•œ SQL ์ฟผ๋ฆฌ๋ฅผ ์ž๋ฐ” ์ฝ”๋“œ๋กœ ์‰ฝ๊ณ  ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ์˜คํ”ˆ์†Œ์Šค ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. ๋งˆ์น˜ SQL์„ ์ž๋ฐ” ์–ธ์–ด์ฒ˜๋Ÿผ ๋‹ค๋ฃจ์–ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ ์ธ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ๋ณต์žกํ•œ ์ฟผ๋ฆฌ ์ž‘์„ฑ์˜ ์–ด๋ ค์›€์„ ํ•ด๊ฒฐํ•˜๊ณ  ์ƒ์‚ฐ์„ฑ์„ ๋†’์—ฌ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ์• ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

1. Querydsl, ์™œ ์‚ฌ์šฉํ• ๊นŒ์š”?

  • ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ: SQL ์ฟผ๋ฆฌ๋ฅผ ๋ฌธ์ž์—ด๋กœ ์ž‘์„ฑํ•˜๋Š” ๋Œ€์‹  ์ž๋ฐ” ์ฝ”๋“œ๋กœ ํ‘œํ˜„ํ•˜์—ฌ ๊ฐ€๋…์„ฑ์„ ๋†’์ด๊ณ  ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ: ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์–ด ๊ฐœ๋ฐœ ์‹œ๊ฐ„์„ ๋‹จ์ถ•์‹œ์ผœ์ค๋‹ˆ๋‹ค.
  • ํƒ€์ž… ์•ˆ์ •์„ฑ: ์ปดํŒŒ์ผ ์‹œ์ ์— ์˜ค๋ฅ˜๋ฅผ ๋ฐœ๊ฒฌํ•˜์—ฌ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๋ฅผ ์ค„์—ฌ์ค๋‹ˆ๋‹ค.
  • ์œ ์—ฐ์„ฑ: ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ORM ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ง€์›ํ•˜์—ฌ ํ™œ์šฉ ๋ฒ”์œ„๋ฅผ ๋„“ํ˜€์ค๋‹ˆ๋‹ค.

 

2. Querydsl ํ•ต์‹ฌ ๊ฐœ๋… ํŒŒํ—ค์น˜๊ธฐ

  • Q-Type: Querydsl์€ ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ Q-Type์ด๋ผ๋Š” ์ฟผ๋ฆฌ ํƒ€์ž…์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด Q-Type์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฟผ๋ฆฌ ์ž‘์„ฑ ์‹œ ํ•„๋“œ๋ช…์ด๋‚˜ ์—”ํ‹ฐํ‹ฐ๋ช…์„ ์ง์ ‘ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • JPA QL: Querydsl์€ JPA QL์ด๋ผ๋Š” JPQL ๊ธฐ๋ฐ˜์˜ ์ฟผ๋ฆฌ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. JPA QL์€ SQL๊ณผ ์œ ์‚ฌํ•˜๋ฉด์„œ๋„ ์—”ํ‹ฐํ‹ฐ ์ค‘์‹ฌ์˜ ์ฟผ๋ฆฌ ์ž‘์„ฑ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • Predicate: Querydsl์—์„œ where ์ ˆ์˜ ์กฐ๊ฑด์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. Predicate๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์กฐ๊ฑด์„ ์กฐํ•ฉํ•˜๊ณ  ์ฟผ๋ฆฌ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Querydsl API: Querydsl์€ ๋‹ค์–‘ํ•œ API๋ฅผ ์ œ๊ณตํ•˜์—ฌ ์ฟผ๋ฆฌ ์ž‘์„ฑ, ์‹คํ–‰, ๊ฒฐ๊ณผ ์ฒ˜๋ฆฌ ๋“ฑ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

 

3. Querydsl, ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•ด์š”!

 

  1. Querydsl ์˜์กด์„ฑ ์ถ”๊ฐ€: ํ”„๋กœ์ ํŠธ์— Querydsl ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  2. Q-Type ์ƒ์„ฑ: ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ Q-Type์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  3. Querydsl ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ: ์ฟผ๋ฆฌ ์‹คํ–‰์„ ์œ„ํ•œ Querydsl ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  4. ์ฟผ๋ฆฌ ์ž‘์„ฑ: Q-Type๊ณผ Querydsl API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›ํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  5. ์ฟผ๋ฆฌ ์‹คํ–‰: ์ž‘์„ฑ๋œ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์Šต๋‹ˆ๋‹ค.

Querydsl ๊ธฐ๋ณธ ์˜ˆ์‹œ: ๊ฐ„๋‹จํ•œ ํšŒ์› ๊ด€๋ฆฌ ๊ธฐ๋Šฅ

Querydsl์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ ํšŒ์› ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ๊ธฐ๋ณธ์ ์ธ ์‚ฌ์šฉ๋ฒ•์„ ์ตํ˜€๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

1. ํ”„๋กœ์ ํŠธ ์„ค์ •

  • Spring Boot ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  Querydsl ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • ํšŒ์› ์—”ํ‹ฐํ‹ฐ(Member)๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
 
Java
@Entity
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private int age;

    // ... getter, setter ๋“ฑ
}

 

2. Q-Type ์ƒ์„ฑ

  • ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ Q-Type์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. (IntelliJ IDEA ๋“ฑ IDE์—์„œ ์ง€์›)

3. Querydsl ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ

  • JPAQueryFactory๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Querydsl ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
 
Java
@PersistenceContext
private EntityManager entityManager;

private JPAQueryFactory queryFactory;

@BeforeEach
public void setUp() {
    queryFactory = new JPAQueryFactory(entityManager);
}

 

4. ์ฟผ๋ฆฌ ์ž‘์„ฑ ๋ฐ ์‹คํ–‰

  • Q-Type๊ณผ Querydsl API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›ํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
 
Java
QMember member = QMember.member;

// ์ด๋ฆ„์œผ๋กœ ํšŒ์› ์กฐํšŒ
Member findMember = queryFactory
    .selectFrom(member)
    .where(member.name.eq("ํ™๊ธธ๋™"))
    .fetchOne();

// ๋‚˜์ด์ˆœ์œผ๋กœ ํšŒ์› ์ •๋ ฌ ํ›„ ์กฐํšŒ
List<Member> members = queryFactory
    .selectFrom(member)
    .orderBy(member.age.asc())
    .fetch();

 

5. ์˜ˆ์‹œ ์ฝ”๋“œ ์ „์ฒด

 
Java
@SpringBootTest
public class MemberRepositoryTest {

    @PersistenceContext
    private EntityManager entityManager;

    private JPAQueryFactory queryFactory;

    @BeforeEach
    public void setUp() {
        queryFactory = new JPAQueryFactory(entityManager);
    }

    @Test
    public void ํšŒ์›_์ด๋ฆ„์œผ๋กœ_์กฐํšŒ() {
        QMember member = QMember.member;

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

        assertThat(findMember.getName()).isEqualTo("ํ™๊ธธ๋™");
    }

    @Test
    public void ํšŒ์›_๋‚˜์ด์ˆœ์œผ๋กœ_์ •๋ ฌํ›„_์กฐํšŒ() {
        QMember member = QMember.member;

        List<Member> members = queryFactory
            .selectFrom(member)
            .orderBy(member.age.asc())
            .fetch();

        assertThat(members.get(0).getAge()).isLessThanOrEqualTo(members.get(1).getAge());
    }
}

 

6. ์‹คํ–‰ ๊ฒฐ๊ณผ

  • ์œ„ ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ํšŒ์› ์ด๋ฆ„์œผ๋กœ ์กฐํšŒํ•˜๊ฑฐ๋‚˜ ๋‚˜์ด์ˆœ์œผ๋กœ ์ •๋ ฌ๋œ ํšŒ์› ๋ชฉ๋ก์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Querydsl ๋™์  ์ฟผ๋ฆฌ ์‚ฌ์šฉ: ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์˜ˆ์‹œ

Querydsl์„ ์‚ฌ์šฉํ•˜์—ฌ ๋™์  ์ฟผ๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ๊ณผ ๊ฐ™์ด ๋‹ค์–‘ํ•œ ์กฐ๊ฑด์— ๋”ฐ๋ผ ์ฟผ๋ฆฌ๊ฐ€ ๋‹ฌ๋ผ์ ธ์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๊ธฐ๋ณธ์ ์ธ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด Querydsl ๋™์  ์ฟผ๋ฆฌ ์‚ฌ์šฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

 

1. ํ”„๋กœ์ ํŠธ ์„ค์ • ๋ฐ ์—”ํ‹ฐํ‹ฐ ์ƒ์„ฑ

  • Spring Boot ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  Querydsl ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์—”ํ‹ฐํ‹ฐ(Product)๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
 
Java
@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String category;
    private int price;

    // ... getter, setter ๋“ฑ
}

 

2. Q-Type ์ƒ์„ฑ ๋ฐ Querydsl ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ

  • ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ Q-Type์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • JPAQueryFactory๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Querydsl ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
 
Java
@PersistenceContext
private EntityManager entityManager;

private JPAQueryFactory queryFactory;

@BeforeEach
public void setUp() {
    queryFactory = new JPAQueryFactory(entityManager);
}

 

3. ๋™์  ์ฟผ๋ฆฌ ์ž‘์„ฑ

  • BooleanBuilder๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋™์  ์กฐ๊ฑด์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฒ€์ƒ‰ ์กฐ๊ฑด์— ๋”ฐ๋ผ BooleanBuilder์— ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
 
Java
@Test
public void ์ƒํ’ˆ_๊ฒ€์ƒ‰() {
    QProduct product = QProduct.product;
    BooleanBuilder builder = new BooleanBuilder();

    String name = "์šด๋™ํ™”";
    String category = "์˜๋ฅ˜";
    Integer price = 10000;

    if (StringUtils.hasText(name)) {
        builder.and(product.name.contains(name));
    }

    if (StringUtils.hasText(category)) {
        builder.and(product.category.eq(category));
    }

    if (price != null) {
        builder.and(product.price.goe(price));
    }

    List<Product> products = queryFactory
        .selectFrom(product)
        .where(builder)
        .fetch();

    // ... ๊ฒฐ๊ณผ ์ฒ˜๋ฆฌ
}

 

4. ์˜ˆ์‹œ ์ฝ”๋“œ ์ „์ฒด

 
Java
@SpringBootTest
public class ProductRepositoryTest {

    @PersistenceContext
    private EntityManager entityManager;

    private JPAQueryFactory queryFactory;

    @BeforeEach
    public void setUp() {
        queryFactory = new JPAQueryFactory(entityManager);
    }

    @Test
    public void ์ƒํ’ˆ_๊ฒ€์ƒ‰() {
        QProduct product = QProduct.product;
        BooleanBuilder builder = new BooleanBuilder();

        String name = "์šด๋™ํ™”";
        String category = "์˜๋ฅ˜";
        Integer price = 10000;

        if (StringUtils.hasText(name)) {
            builder.and(product.name.contains(name));
        }

        if (StringUtils.hasText(category)) {
            builder.and(product.category.eq(category));
        }

        if (price != null) {
            builder.and(product.price.goe(price));
        }

        List<Product> products = queryFactory
            .selectFrom(product)
            .where(builder)
            .fetch();

        // ... ๊ฒฐ๊ณผ ์ฒ˜๋ฆฌ
    }
}

 

5. ์‹คํ–‰ ๊ฒฐ๊ณผ

  • ์œ„ ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๊ฒ€์ƒ‰ ์กฐ๊ฑด์— ๋”ฐ๋ผ ์ƒํ’ˆ ๋ชฉ๋ก์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Querydsl ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ: ๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ์™€ ํ•จ๊ป˜ ์•Œ์•„๋ณด๊ธฐ

Querydsl์„ ์‚ฌ์šฉํ•˜์—ฌ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๊ธฐ๋ณธ์ ์ธ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด Querydsl ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

1. ํ”„๋กœ์ ํŠธ ์„ค์ • ๋ฐ ์—”ํ‹ฐํ‹ฐ ์ƒ์„ฑ

  • Spring Boot ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  Querydsl ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ ๋Œ€์ƒ ์—”ํ‹ฐํ‹ฐ(Product)๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
 
Java
@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private int price;

    // ... getter, setter ๋“ฑ
}

 

2. Q-Type ์ƒ์„ฑ ๋ฐ Querydsl ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ

  • ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ Q-Type์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • JPAQueryFactory๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Querydsl ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
 
Java
@PersistenceContext
private EntityManager entityManager;

private JPAQueryFactory queryFactory;

@BeforeEach
public void setUp() {
    queryFactory = new JPAQueryFactory(entityManager);
}

 

3. ํŽ˜์ด์ง• ์ฟผ๋ฆฌ ์ž‘์„ฑ

  • Querydsl์˜ offset()๊ณผ limit()์„ ์‚ฌ์šฉํ•˜์—ฌ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  • offset()์€ ์‹œ์ž‘ ์œ„์น˜๋ฅผ, limit()์€ ํŽ˜์ด์ง€ ํฌ๊ธฐ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
 
Java
@Test
public void ์ƒํ’ˆ_ํŽ˜์ด์ง•() {
    QProduct product = QProduct.product;
    int page = 0; // ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ (0๋ถ€ํ„ฐ ์‹œ์ž‘)
    int size = 10; // ํŽ˜์ด์ง€ ํฌ๊ธฐ

    List<Product> products = queryFactory
        .selectFrom(product)
        .orderBy(product.id.asc()) // ์ •๋ ฌ ๊ธฐ์ค€ (id ์—ญ์ˆœ)
        .offset(page * size) // ์‹œ์ž‘ ์œ„์น˜ ๊ณ„์‚ฐ
        .limit(size) // ํŽ˜์ด์ง€ ํฌ๊ธฐ
        .fetch();

    // ... ๊ฒฐ๊ณผ ์ฒ˜๋ฆฌ
}

 

4. ์˜ˆ์‹œ ์ฝ”๋“œ ์ „์ฒด

 
Java
@SpringBootTest
public class ProductRepositoryTest {

    @PersistenceContext
    private EntityManager entityManager;

    private JPAQueryFactory queryFactory;

    @BeforeEach
    public void setUp() {
        queryFactory = new JPAQueryFactory(entityManager);
    }

    @Test
    public void ์ƒํ’ˆ_ํŽ˜์ด์ง•() {
        QProduct product = QProduct.product;
        int page = 0; // ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ (0๋ถ€ํ„ฐ ์‹œ์ž‘)
        int size = 10; // ํŽ˜์ด์ง€ ํฌ๊ธฐ

        List<Product> products = queryFactory
            .selectFrom(product)
            .orderBy(product.id.asc()) // ์ •๋ ฌ ๊ธฐ์ค€ (id ์—ญ์ˆœ)
            .offset(page * size) // ์‹œ์ž‘ ์œ„์น˜ ๊ณ„์‚ฐ
            .limit(size) // ํŽ˜์ด์ง€ ํฌ๊ธฐ
            .fetch();

        // ... ๊ฒฐ๊ณผ ์ฒ˜๋ฆฌ
    }
}

 

5. ์‹คํ–‰ ๊ฒฐ๊ณผ

  • ์œ„ ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ƒํ’ˆ ๋ชฉ๋ก์„ ํŽ˜์ด์ง€ ๋‹จ์œ„๋กœ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.