Spring/Spring Data JPA

Specification

snorlax1106 2025. 2. 17. 16:38

Specification이란?

 

Specifications :: Spring Data JPA

Example 4. Using a Specification to delete entries. Specification ageLessThan18 = (root, query, cb) -> cb.lessThan(root.get("age").as(Integer.class), 18) userRepository.delete(ageLessThan18); The Specification builds up a criteria where the age field (cast

docs.spring.io

JPA의 Criteria API를 기반으로 동적 쿼리를 생성할 수 있도록 도와주는 인터페이스

 

JpaSecificationExecutor

동적 쿼리 실행을 가능하게 하려면 JpaSpecificationExecutor<T>를 JPA Repository에 추가해야 Specification 기반 검색을 위한 다양한 메서드를 제공받을 수 있다.

public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}

 

Specification 핵심 구성 요소

@Override
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
    // 여기서 root, query, criteriaBuilder를 활용하여 조건을 생성
}
  • root
    • 엔티티의 기본 루트 객체로, 조회할 엔티티를 나타낸다.
    • root.get(”필드명”)을 사용하여 필드에 접근 가능하다.
  • query
    • 실행될 쿼리 자체를 나타낸다. 정렬, 그룹핑 등을 설정할 때 사용된다.
  • criteriaBuilder
    • 조건을 생성하는 빌더 객체. where, and, or, like 등 다양한 메서드를 제공한다.

 

Root<T> 객체 사용 예제

criteriaBuilder.equal(root.get("name"), "Alice") // name = 'Alice'
criteriaBuilder.greaterThan(root.get("age"), 25) // age > 25
Join<User, Order> orderJoin = root.join("orders"); // User와 Order 테이블 조인
criteriaBuilder.equal(orderJoin.get("status"), "DELIVERED") // 주문 상태가 DELIVERED인 경우

 

CriteriaQuery<?> 객체 사용 예제

query.orderBy(criteriaBuilder.desc(root.get("age"))); // ORDER BY age DESC
query.groupBy(root.get("department")); // GROUP BY department

 

CriteriaBuilder 객체 기본 조건 메서드 및 사용 예제

  • equal(): 값이 같은지 비교
criteriaBuilder.equal(root.get("name"), "Alice") → name = 'Alice'
  • notEqual(): 값이 다른지 비교
criteriaBuilder.notEqual(root.get("name"), "Bob") → name <> 'Bob'
  • greaterThan(): 초과 비교 (숫자)
criteriaBuilder.greaterThan(root.get("age"), 25) → age > 25
  • greaterThanOrEqualTo(): 이상 비교 (숫자)
criteriaBuilder.greaterThanOrEqualTo(root.get("age"), 25) → age >= 25
  • lessThan(): 미만 비교 (숫자)
criteriaBuilder.lessThan(root.get("age"), 30) → age < 30
  • lessThanOrEqualTo(): 이하 비교 (숫자)
criteriaBuilder.lessThanOrEqualTo(root.get("age"), 30) → age <= 30
  • like(): 특정 문자열 패턴 포함
criteriaBuilder.like(root.get("email"), "%gmail.com") → email LIKE '%gmail.com'
  • in(): 여러 값 중 하나인지 검사
criteriaBuilder.in(root.get("status")).value("ACTIVE").value("INACTIVE") → status IN ('ACTIVE', 'INACTIVE')
  • between(): 값의 범위 검사
criteriaBuilder.between(root.get("age"), 20, 30) → age BETWEEN 20 AND 30