티스토리 뷰

코프링으로 개발 시 마주친 생각 관련 포스팅입니다.

개발 환경은 다음과 같습니다.

  • Spring Boot Version : 3.0.1
  • Java Version : 17
  • Kotlin Version : 1.8.21

배경

JPA를 사용하면서 흔히 사용했던 Optional에 대해 생각해봤습니다.

package com.laboratorykkoon9.kotlinspring.cafe.repository

import com.laboratorykkoon9.kotlinspring.cafe.domain.Cafe
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
import org.springframework.transaction.annotation.Transactional
import java.util.*

@Repository
interface CafeRepository: JpaRepository<Cafe, Long> {
    override fun findAll(page: Pageable): Page<Cafe>

    @Transactional(readOnly = true)
    fun findByName(name: String): Optional<Cafe>
}

일단 Optional은 Java.util 라이브러리에 존재합니다.

또한, 이 메서드를 사용하려면 다음과 같이 사용해야 합니다.

// 1번째
val cafe = cafeRepository.findByName(it.name)
if (cafe.isPresent) {
    throw IllegalArgumentException("${it.name}은(는) 이미 존재하는 이름입니다.")
}

// 2번째
val cafe = cafeRepository.findByName(it.name).orElseThrow { IllegalArgumentException("${it.name}은(는) 이미 존재하는 이름입니다.") }

저는 if 문이나 orElseThrow 말고 다른걸 쓰고 싶었습니다.

물론 잘못된 건 아니고 코틀린 스럽게 짜고 싶어서 찾아봤습니다.

앨비스 연산자

코틀린에서 제공하는 엘비스 연산자를 사용했습니다.

package com.laboratorykkoon9.kotlinspring.cafe.repository

import com.laboratorykkoon9.kotlinspring.cafe.domain.Cafe
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
import org.springframework.transaction.annotation.Transactional
import java.util.*

@Repository
interface CafeRepository: JpaRepository<Cafe, Long> {
    override fun findAll(page: Pageable): Page<Cafe>

    @Transactional(readOnly = true)
    fun findByName(name: String): Cafe?
}

먼저 Optional이 아닌 물음표(?)를 사용해서 nullable하게 변경하였습니다.

그 다음, findByName을 다음과 같이 사용할 수 있습니다.

cafeRepository.findByName(it.name)
    ?: throw IllegalArgumentException("${it.name}은(는) 이미 존재하는 이름입니다.")

cafeRepository.findByName(it.name)의 결과값이 null이라면 Exception을 던지는 코드입니다.

결론

엘비스 연산자를 사용하여 Optional을 피해보았습니다.

코틀린 인 액션 책에서는 코틀린에서만 제공하는 기능은 웬만하면 사용하지 않는걸 권고합니다.

코틀린을 모르는 사람들이 보더라도 직관적인 코드를 짜라는 이유였습니다.

사실 코틀린을 모르는 입장에서는 첫 번째 코드가 더 직관적이기 떄문입니다.

같이 협업하는 사람들과 논의해서 사용하면 좋을 것 같습니다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함