Kotlin-Jdsl Dynamic Query 작성법

Picbel·2022년 7월 23일
2

Kotlin

목록 보기
1/4
post-thumbnail

kotlin에서 Query-dsl을 사용하다 보면 이래저래 불편함이 있죠.
그렇다고 안 쓰기엔 JPA로 동적쿼리를 작성하기엔 JPA로는 굉장히 불편하죠
그래서 Kotlin-Jdsl을 사용하기로 하였습니다.
라인에서 만든 라이브러리죠 github 링크입니다 - kotlin-jdsl

그런데 구글링 중 Kotlin-Jdsl로 Dynamic Query 작성하는 법을 찾을 수가 없더라고요
그래서 제가 사용하는 방법을 공유합니다. 더 좋은 방법이 있으면 댓글 부탁드립니다 :)

repository를 작성해보겠습니다.

interface PostRepository {
    fun findByTitleOrAuthor(title: String?, authorName: String?) : List<Post>
}

@Repository
internal class PostRepositoryImpl(
    private val queryFactory: SpringDataQueryFactory,
) : PostRepository {
    override fun findByTitleOrAuthor(title: String?, authorName: String?): List<Post> {
        return queryFactory.listQuery<PostEntity> {
            select(entity(PostEntity::class))
            from(entity(PostEntity::class))
            fetch(PostEntity::author)
            // title과 authorName의 값에 따라 동적쿼리를 작성합니다
            where(dynamicAndFactory(title, authorName))
        }
    }
}

이제 title과 authorName으로 동적쿼리를 작성해보겠습니다.

private fun <T> SpringDataCriteriaQueryDsl<T>.dynamicAndFactory(
	title: String?, 
	authorName: String?
): PredicateSpec {
    return and(
        title?.let { column(PostEntity::title).equal(title) },
        authorName?.let { column(AuthorEntity::name).equal(authorName)}
    )
}

다음과 같은 방식으로 작성가능합니다.
코틀린의 확장함수기능을 활용하여 작성하였습니다.
title과 authorName이 null이면 where조건이 작성되지 않습니다.

검증하는 코드는 다음과 같습니다

	... 데이터 setup 
    
    @Autowired
    private lateinit var sut: PostRepositoryImpl
    
	@Test
    fun `제목과 작가를 null로 조회합니다`() {
         //given //when
        val result = sut.findByTitleOrAuthor(null, null)
        // then
        assertEquals(result.size, 12)
    }

    @Test
    fun `제목과 작가를 입력하여 조회합니다`() {
         //given //when
        val result = sut.findByTitleOrAuthor("1", "lyn")
        //then
        assertEquals(result.size, 1)

    }

    @Test
    fun `제목만 조회합니다`() {
        //given //when
        val result = sut.findByTitleOrAuthor("1", null)
        // then
        assertEquals(result.size, 2)
    }

    @Test
    fun `작가만 조회합니다`() {
        //given //when
        val result = sut.findByTitleOrAuthor(null, "gon")
        //then
        assertEquals(result.size, 7)
    }

위에서 부터 차례로 실행되는 query를 확인하여보겠습니다

  1. 제목과 작가를 null로 조회합니다

  1. 제목과 작가를 입력하여 조회합니다

  1. 제목만 조회합니다

  1. 작가만 조회합니다

네 보시면 query가 예상대로 나가는걸 확인 할수 있습니다.
and를 제외한 or, between또한 확장함수를 응용하면 충분히 작성 하실수 있습니다.

예제코드는 해당 링크에서 study-kotlin-jsdl 확인하실수 있습니다.

profile
Software Developer

0개의 댓글