[스프링] JPA 동적 쿼리 생성

스프링 프레임워크에서 JPA를 사용하는 경우, 동적 쿼리를 생성해야 하는 경우가 많습니다. 동적 쿼리란 실행 시점에 쿼리의 일부 또는 전체를 동적으로 결정하는 쿼리를 의미합니다. 이러한 동적 쿼리를 생성하는 방법을 살펴보겠습니다.

JPA Criteria Query

스프링 프레임워크에서 JPA를 이용하여 동적 쿼리를 생성하는 방법 중 하나는 JPA Criteria Query를 사용하는 것입니다. JPA Criteria Query는 프로그래밍 언어로 쿼리를 작성하고 컴파일 시점에 오류를 확인할 수 있는 장점이 있습니다. 또한 동적 쿼리를 쉽게 생성할 수 있다는 장점도 있습니다.

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Entity> query = cb.createQuery(Entity.class);
Root<Entity> root = query.from(Entity.class);

Path<String> namePath = root.get("name");
Predicate condition = cb.equal(namePath, "someName");

query.select(root).where(condition);

List<Entity> result = entityManager.createQuery(query).getResultList();

위의 예제에서는 CriteriaBuilder를 사용하여 동적 쿼리를 생성하는 방법을 보여줍니다.

QueryDSL

또 다른 방법으로 QueryDSL이라는 라이브러리를 사용하는 것이 있습니다. QueryDSL은 JPA Criteria Query보다 더 유연하고 간결한 문법을 제공하여 동적 쿼리를 작성하는 데 유용합니다.

JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
QEntity entity = QEntity.entity;

List<Entity> result = queryFactory.selectFrom(entity)
                                  .where(entity.name.eq("someName"))
                                  .fetch();

위의 예제에서는 QueryDSL을 사용하여 동적 쿼리를 생성하는 방법을 보여줍니다.

Specification과 Criteria

스프링 데이터 JPA에서는 Specification과 Criteria를 함께 사용하여 동적 쿼리를 생성하는 방법도 제공합니다. Specification은 조건을 위한 클래스이고, Criteria는 쿼리를 위한 클래스입니다.

public Specification<Entity> hasName(String name) {
    return (root, query, cb) -> cb.equal(root.get("name"), name);
}

Specification<Entity> spec = Specifications.where(hasName("someName"));

List<Entity> result = repository.findAll(spec);

위의 예제에서는 Specification과 Criteria를 함께 사용하여 동적 쿼리를 생성하는 방법을 보여줍니다.

이처럼 스프링에서는 다양한 방법으로 JPA 동적 쿼리를 생성할 수 있습니다. 각 방법마다 장단점이 있으니 상황에 맞게 적합한 방법을 선택하여 사용할 수 있습니다.

참고문헌: