집돌이 공대남 IT

JPA 프로그래밍 마스터하기: 중급부터 전문가까지 실습을 통한 학습(6) 본문

IT/웹개발

JPA 프로그래밍 마스터하기: 중급부터 전문가까지 실습을 통한 학습(6)

집공이 2023. 9. 3. 12:00

JPA 동적 쿼리의 활용과 페이징 기능 구현

안녕하세요, 집돌이 공대남입니다.오늘도 저와 함께 JPA에 대한 여행을 이어가 주셔서 감사합니다.

이번 포스트에서는 동적 쿼리를 실제로 어떻게 활용하는지, 그리고 페이징이라는 중요한 웹 애플리케이션 기능을 어떻게

구현하는지에 대해 알아보려 합니다.

동적 쿼리란?

먼저 동적 쿼리에 대해 간단히 설명하자면, 프로그램 실행 중에 SQL 문을 생성하여 데이터베이스에 접근하는 방식을 말합니다. 이는 사용자의 요청에 따라 SQL 문이 변경되어야 할 경우 유용하게 사용될 수 있습니다. 이번 포스트에서는 JPA와 QueryDSL을 활용하여 동적 쿼리를 구현하는 방법을 알아보겠습니다.

 

페이징 기능과 동적 쿼리

페이징이란 데이터베이스에서 가져온 데이터를 페이지 단위로 나눠서 보여주는 기능을 의미합니다. 페이징은 웹 애플리케이션에서 많은 데이터를 효율적으로 관리하기 위한 필수적인 기능입니다. QueryDSL은 이러한 페이징 기능을 쉽게 구현할 수 있도록 지원하며, 이는 동적 쿼리와 함께 사용될 수 있습니다.

다음 코드는 동적 쿼리와 페이징 기능을 결합한 간단한 예시입니다.

public class BookRepositoryCustomImpl implements BookRepositoryCustom {
    @PersistenceContext
    private EntityManager em;

    @Override
    public Page<Book> find(BookSearchCondition condition, Pageable pageable) {
        JPAQueryFactory query = new JPAQueryFactory(em);
        QBook book = QBook.book;

        BooleanBuilder builder = new BooleanBuilder();

        if (StringUtils.hasText(condition.getTitle())) {
            builder.and(book.title.contains(condition.getTitle()));
        }

        if (condition.getGenre() != null) {
            builder.and(book.genre.eq(condition.getGenre()));
        }

        if (condition.getPriceGoe() != null) {
            builder.and(book.price.goe(condition.getPriceGoe()));
        }

        if (condition.getPriceLoe() != null) {
            builder.and(book.price.loe(condition.getPriceLoe()));
        }

        QueryResults<Book> results = query.selectFrom(book)
                                          .where(builder)
                                          .offset(pageable.getOffset())
                                          .limit(pageable.getPageSize())
                                          .fetchResults();

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

이 코드에서 주목할 점은 다음과 같습니다:

  1. Pageable 인터페이스를 사용해 페이징 정보를 전달받습니다. Pageable 객체는 Spring Data에서 제공하는 인터페이스로, 페이지 번호와 페이지당 데이터 수 등 페이징에 필요한 정보를 담고 있습니다.
  2. JPAQueryFactory를 사용해 쿼리를 생성합니다. selectFrom() 메소드로 조회할 엔티티를 지정하고, where() 메소드로 조건을 설정합니다.
  3. BooleanBuilder를 사용해 동적 쿼리를 생성합니다. 검색 조건이 있을 경우에만 해당 조건을 쿼리에 추가하므로, 검색 조건의 여부에 따라 동적으로 쿼리를 생성할 수 있습니다.
  4. offset()limit() 메소드를 사용해 페이징을 적용합니다. offset()은 건너뛸 데이터의 수를, limit()은 조회할 데이터의 수를 지정합니다. 이는 SQL의 OFFSET과 LIMIT 절에 해당합니다.
  5. 마지막으로, fetchResults() 메소드를 사용해 쿼리 결과를 가져옵니다. 이 메소드는 조회된 데이터뿐 아니라 전체 데이터 수도 함께 반환합니다. 이를 통해 전체 페이지 수

를 계산할 수 있습니다.

이처럼 동적 쿼리와 페이징 기능을 활용하면 사용자의 요청에 따라 유연하게 대응하며, 많은 데이터를 효율적으로 관리할 수 있습니다.

이상으로 JPA와 QueryDSL을 활용한 동적 쿼리와 페이징 기능에 대해 알아보았습니다.

이번 포스트가 도움이 되셨길 바랍니다. 다음 포스트에서는 JPA의 성능 최적화에 대해 자세히 알아보도록 하겠습니다. 감사합니다!