Spring Data JPA - Query


Spring Data JPA 쿼리 메소드 기능
@Query, 리포지토리 메소드에 쿼리 정의하기, Dto조회하기, 파라미터 바인딩

@Query의 기본 개념

Spring Data JPA에서는 메서드 이름으로 간단한 쿼리를 생성해 주는 기능이 있지만, 복잡한 쿼리를 작성해야 할 때 @Query를 사용하면 큰 도움이 됩니다.

MemberRepository.kt
1
2
3
4
5
6
interface MemberRepository: JpaRepository<Member, Long> {

@Query("select m from Member m where m.username = :username and m.age = :age")
fun findUser(@Param("username") username: String, @Param("age") age: Int): List<Member>

}

이렇게 메서드에 직접 쿼리를 정의하면, 이름 없는 Named 쿼리처럼 사용할 수 있습니다. 이 방식의 장점은 애플리케이션 실행 시점에 문법 오류를 미리 확인할 수 있다는 점입니다.

단순 값과 DTO 조회

@Query를 활용하면, 엔터티뿐만 아니라 단순 값 혹은 DTO도 쉽게 조회할 수 있습니다.

1
2
@Query("select m.username from Member m")
fun findUsernameList(): List<String>

DTO로 직접 조회하고 싶을 때는 JPA의 new 명령어를 사용해야 합니다.

1
2
@Query("select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join m.team t")
fun findMemberDto() :List<MemberDto>

여기서 주의해야 할 점은 DTO의 생성자의 순서와 쿼리에서 select하는 컬럼의 순서가 일치해야 한다는 것입니다.

파라미터 바인딩 깊게 알아보기

  • 위치 기반 바인딩:
    이 방식은 ? 뒤에 인덱스를 붙여서 사용합니다. 인덱스는 0부터 시작합니다.

    1
    select m from Member m where m.username = ?0

    이 방식의 단점은 파라미터의 순서가 바뀌면 쿼리의 의미가 달라질 수 있습니다.

  • 이름 기반 바인딩:
    쿼리 내부에서 사용할 변수명 앞에 :를 붙여 사용합니다. 이후 @Param 어노테이션을 이용해 메서드 파라미터와 매핑시킵니다.

    1
    2
    @Query("select m from Member m where m.username = :name")
    fun findMembers(@Param("name") username: String);

    이 방식의 장점은 쿼리의 의미가 바뀌지 않고, 코드의 가독성이 좋아집니다.

컬렉션으로 파라미터 바인딩하기

IN절을 활용하여 여러 값을 한번에 조회할 때는 Collection 타입을 파라미터로 사용합니다.

1
2
@Query("select m from Member m where m.username in :names")
fun findByNames(@Param("names") names: List<String>): List<Member>

JPA와 Spring Data JPA의 강력한 기능 중 하나인 @Query를 활용하면 복잡한 쿼리도 깔끔하게 관리할 수 있습니다.

소스코드

참조