스프링에서 파라미터 바인딩을 할 때 위치 기반
, 이름 기반
두 가지를 사용할 수 있다.
이름 기반
파라미터 바인딩을 사용할 것.select m from Member m where m.username = ?0 //위치 기반
select m from Member m where m.username = :name //이름 기반
public interface MemberRepository extends JpaRepository<Member, Long> {
@Query("select m from Member m where m.username = :name")
Member findMembers(@Param("name") String username);
}
Collection
타입으로 in절 지원@Query("select m from Member m where m.username in :names")
List<Member> findByNames(@Param("names") List<String> names);
List<Member> findByUsername(String name); //컬렉션
Member findByUsername(String name); //단건
Optional<Member> findByUsername(String name); //단건 Optional
결과가 없다면 : 빈 컬렉션(empty collection) 반환
null
반환javax.persistence.NonUniqueResultException
예외 발생orElseXXX
(데이터가 있을 수도 없을 수도 있는 경우)단건으로 지정한 메서드를 호출하면 스프링 데이터 JPA는 내부에서 JPQL Query.getSingleResult() 메서드를 호출한다. 이 메서드를 호출했을 때 조회 결과가 없으면 javax.persistence.NoResultException 예외가 발생하는데 개발자 입장에서 다루기가 상당히 불편하다. 스프링 데이터 JPA는 단건을 조회할 때 이 예외가 발생하면 예외를 무시하고 대신에 null 을 반환한다.
예외처리도 쉽고 프론트단과 얘기해서 어떤 식으로 반환해줄지 정하기도 편해서 Optional이 좋다.
@Param
어노테이션은 매핑할 때 사용하는 어노테이션이다.
@Param
어노테이션을 붙이면 본인이 원하는 이름으로 mapper에서 사용할 수 있다. 일반적으로 Spring Data JPA 레포지토리에서 사용된다. Spring Data JPA는 메서드 이름을 기반으로 쿼리를 생성하는 기능을 제공하지만, 때로는 메서드 이름만으로는 충분하지 않을 때가 있다. 이런 경우에 @Param
어노테이션을 사용하여 메서드 파라미터와 쿼리의 매개변수를 매핑할 수 있다.
public interface UserRepository extends JpaRepository<User, Long> {
@Query("SELECT u FROM User u WHERE u.username = :name")
User findByUsername(@Param("name") String username);
}
이 예제에서는 @Query
어노테이션을 사용하여 JPQL 쿼리를 정의하고, @Param
어노테이션을 사용하여 메서드 파라미터인 username을 JPQL 쿼리에서 사용되는 :name 매개변수와 연결한다. 이렇게 하면 Spring Data JPA가 메서드 파라미터와 JPQL 쿼리의 매개변수를 연결하고 실행 시에 쿼리를 올바르게 바인딩할 수 있다.
@Param
어노테이션은 또한 여러 개의 파라미터를 가진 메서드에서 파라미터를 명시적으로 지정할 때도 유용하며, 파라미터 이름을 변경하고자 할 때도 사용될 수 있다.
다시 말해서, 위 코드에서 @Query
어노테이션 내부의 "SELECT u FROM User u WHERE u.username = :name"
부분에서 :name은 @Param("name") 어노테이션을 통해 명명된 메서드의 파라미터인 name과 연결된다. 이렇게 하면 Spring Data JPA가 name 파라미터 값을 :name에 매핑하고 쿼리를 실행할 때 파라미터를 올바르게 바인딩한다.
따라서 @Param 어노테이션은 메서드 파라미터와 쿼리의 매개변수를 연결하는데 사용되며, 이를 통해 명시적으로 파라미터를 바인딩하고 원하는 대로 쿼리를 작성할 수 있다 ~!