프로젝트를 진행하다 보면 다양한 조건을 기반으로 데이터를 검색해야 할 때가 많습니다. 예를 들어, title, englishLevel, city와 같은 조건을 이용해 Circle 데이터를 검색할 때, 이들 조건이 null일 경우 해당 조건을 무시하고 싶을 수 있습니다. 이런 경우 Kotlin JDSL에서는 null 값 조건을 쉽게 무시하는 방법을 제공하며, 이번 글에서는 이를 어떻게 적용할 수 있는지 설명드리겠습니다.

 

문제 상황

아래와 같은 쿼리를 작성했다고 가정해보겠습니다.

override fun findCirclesByPagination(pageable: Pageable, request: CircleSearchRequest?)
: Page<CirclePageResponse?> {
    return kotlinJdslJpqlExecutor.findPage(pageable) {
        selectNew<CirclePageResponse>(
                path(Circle::id),
                path(Circle::thumbnailUrl),
                path(Circle::title),
                path(Circle::introduction),
                path(Member::profile).`as`(expression("leaderProfile")),
                path(Member::nickname).`as`(expression("leaderName")),
                path(Circle::englishLevel),
                path(Circle::city),
                path(Circle::capacity),
                path(Circle::totalView),
                path(Circle::totalLike),
        ).from(
                entity(Circle::class),
                join(Circle::leader)
        ).whereAnd(
                path(Circle::title).like("%${request?.title}%"),
                path(Circle::englishLevel).eq(request?.level),
                path(Circle::city).eq(request?.city)
        )
    }
}

여기서 우리는 title, englishLevel, city 세 가지 조건을 사용하고 있습니다. 하지만 이 필드들 중 하나라도 null일 경우 쿼리에서 해당 조건을 무시해야 할 때 어떻게 해야 할까요?

 

해결 방법: 조건을 let으로 감싸기

Kotlin JDSL에서는 whereAnd 블록 내에서 조건을 동적으로 추가할 수 있습니다. let 함수를 활용해 각 조건이 null이 아닐 때만 적용되도록 설정해보겠습니다.

 

override fun findCirclesByPagination(pageable: Pageable, request: CircleSearchRequest?)
: Page<CirclePageResponse?> {
    return kotlinJdslJpqlExecutor.findPage(pageable) {
        selectNew<CirclePageResponse>(
                path(Circle::id),
                path(Circle::thumbnailUrl),
                path(Circle::title),
                path(Circle::introduction),
                path(Member::profile).`as`(expression("leaderProfile")),
                path(Member::nickname).`as`(expression("leaderName")),
                path(Circle::englishLevel),
                path(Circle::city),
                path(Circle::capacity),
                path(Circle::totalView),
                path(Circle::totalLike),
        ).from(
                entity(Circle::class),
                join(Circle::leader)
        ).whereAnd(
                request?.title?.let { path(Circle::title).like("%$it%") },
                request?.level?.let { path(Circle::englishLevel).eq(it) },
                request?.city?.let { path(Circle::city).eq(it) }
        )
    }
}

 

코드 설명

  1. 조건 추가를 위한 let 사용: request?.title, request?.level, request?.city가 각각 null이 아닐 때만 let 블록 내부의 조건이 실행되어 쿼리에 추가됩니다.
  2. null 값 무시: title, level, city 중 하나라도 null이면 해당 조건은 자동으로 쿼리에서 제외됩니다.

동작 방식 예시

  • title만 null인 경우: englishLevel과 city만 조건으로 포함됩니다.
  • 모든 값이 null인 경우: 조건 없이 전체 결과가 반환됩니다.

이를 통해 null 조건을 유연하게 무시하고 원하는 조건에 따라 필터링된 결과를 반환받을 수 있습니다.

 

마무리

Kotlin JDSL에서 조건을 동적으로 설정하는 것은 상당히 직관적이며, let 함수와 같은 Kotlin의 기능을 활용해 쿼리의 가독성을 높일 수 있습니다. 이 방식은 특히 검색 기능을 구현할 때 유용하며, nullable 필드를 조건으로 사용할 때 코드의 안정성과 효율성을 높여줍니다.

이번 글에서는 Kotlin JDSL을 사용해 조건이 null인 경우 쿼리에서 해당 조건을 제외하는 방법을 살펴보았습니다. 앞으로 JDSL을 활용해 다양한 쿼리를 동적으로 구성할 때 큰 도움이 되길 바랍니다.

'Kotlin-Jdsl' 카테고리의 다른 글

Kotlin JDSL 도입기: Page 타입 응답값 반환하기  (1) 2024.11.03

+ Recent posts