본문 바로가기
Spring

[Spring] Spring Boot + Kotlin + JPA Native Query 사용법 (1) - @Query

by 노력남자 2023. 6. 25.
반응형

이번 포스팅부터 Spring + Kotlin + JPA Native Query 사용법에 대해 알아보려고 한다.

 

JPA를 사용하다보면 어쩔 수 없이 JPQL이 아닌 native query를 사용해야 할 때가 있다.

 

native query를 어떻게 사용할 수 있는지, 어떤 대안이 있는지, 어떤 장단점이 있는지 하나씩 알아보려고 한다.

 

이번 포스팅에선 @Query 어노테이션을 이용해 native query를 작성하는 방법에 대해 알아보겠다.

 

@Query 사용법

 

@Query 파라미터 중 nativeQuery를 true로 주고 value에 native query를 작성하면 native query가 실행된다.

 

@Query(
    value = "natvie query",
    nativeQuery = true
)
fun ...

 

아주 심플하다.

 

@Query는 2가지의 리턴 타입를 사용할 수 있다.

 

1. @Entity class

 

@Entity
class Address(
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long = 0,
    var name: String,
    var phoneNum: String,
    var zipCode: String,
    var address1 : String,
    var address2: String
)

 

interface AddressRepository : JpaRepository<Address, Long> {

    @Query(
        value = """
            SELECT * // *로 해줘야 entity로 받을 수 있다.
            FROM address
            WHERE name = :name
        """,
        nativeQuery = true
    )
    fun findByName(name: String): Address
}

 

2. Interface

 

interface NameOfAddress {
    val name: String
}

 

interface AddressRepository : JpaRepository<Address, Long> {

    @Query(
        value = """
            SELECT name
            FROM address
            WHERE name = :name
        """,
        nativeQuery = true
    )
    fun findByName(name: String): NameOfAddress
}

 

@Query 장점

 

심플하다.

 

@Query 단점

 

동적 쿼리를 작성하기가 어렵거나, 불가능할 수도 있다.

 

예)

 

name 값이 있는 경우 name 조건을,

address1 값이 있는 경우 address1 조건을,

address2 값이 있는 경우 address2 조건을 추가하고 싶다면?

 

아래와 같이 작성해야 한다.

 

@Query(
        value = """
            SELECT name
            FROM address
            WHERE 
                (:name is null or name = :name)
                and (:address1 is null or address1 = :address1)
                and (:address2 is null or address2 = :address2)
        """,
        nativeQuery = true
    )
    fun findByName(
        name: String? = null,
        address1: String? = null,
        address2: String? = null
    ): NameOfAddress

 

실행시켜보면 아래와 같이 쿼리가 나가는데 이쁘지가 않다.

 

SELECT
    name             
FROM
    address             
WHERE
    (
        ? is null 
        or name = ?
    )                 
    and (
        ? is null 
        or address1 = ?
    )                 
    and (
        ? is null 
        or address2 = ?
    )

 

그나마 위에 조건은 가능한데

 

파라미터 값에 따라 아예 쿼리가 달라져야 하는 상황이면 불가능하다.

반응형

댓글