Spring JPA에서 조건에 따라 검색 조건이 달라지는 쿼리를 작성할 때 자주 사용하는 기법이 바로 Dynamic Filter, 즉 동적 필터링입니다.
사용자의 입력 값이 존재하는 경우에만 조건을 추가하고, 그렇지 않으면 해당 조건을 무시하는 방식으로 단일 쿼리로 다양한 경우를 처리할 수 있게 합니다.
@Query("SELECT t" +
" FROM Todo t " +
"LEFT JOIN FETCH t.user u " +
"WHERE (:weather IS NULL OR t.weather = :weather)" +
"AND (:searchStartDate IS NULL OR t.modifiedAt >= :searchStartDate) " +
"AND (:searchEndDate IS NULL OR t.modifiedAt <= :searchEndDate)" +
"ORDER BY t.modifiedAt DESC")
Page<Todo> findAllOrSearch(
@Param("weather") String weather,
@Param("searchStartDate") LocalDateTime searchStartDate,
@Param("searchEndDate") LocalDateTime searchEndDate,
Pageable pageable);
:weather IS NULL OR t.weather = :weather
→ weather 파라미터가 null이면 조건 무시 (모든 날씨 허용)
→ 값이 있으면 해당 값과 일치하는 항목만 필터링
:start IS NULL OR t.modifiedAt >= :start
→ 시작일이 null이면 조건 무시
→ 값이 있으면 해당 시점 이후의 데이터만 필터링
:end IS NULL OR t.modifiedAt <= :end
→ 종료일이 null이면 조건 무시
→ 값이 있으면 해당 시점 이전의 데이터만 필터링
| 개념 | 설명 |
|---|---|
| Dynamic Filter | 조건 값이 null인지 여부에 따라 WHERE 절 조건을 유동적으로 포함하거나 생략 |
| Optional Query Parameter | 검색 요청 시 클라이언트가 보낼 수도, 생략할 수도 있는 파라미터 |
| null check + OR 패턴 | (:param IS NULL OR ...)을 통해 조건 생략 가능하게 만듦 |
| @Query | JPQL로 커스텀 쿼리를 직접 작성하여 동적 조건 적용 가능 |
QueryBuilder로 분리하거나 QueryDSL 도입 고려@Query 방식은 빠르게 구현 가능하지만, 복잡한 조합에는 한계가 있음Specification 또는 Criteria API 방식과 비교해보는 것이 좋음동적 필터링(Dynamic Filter)은
null조건을 이용해 JPQL에서 다양한 검색 조건을 유연하게 적용하는 기법입니다.
불필요한 쿼리 메서드의 중복을 줄이고, 검색 기능 구현에 매우 유용합니다.