spring - 파라미터 바인딩

Chooooo·2023년 9월 8일
0

스프링 데이터 JPA

목록 보기
1/1

😎 파라미터 바인딩

스프링에서 파라미터 바인딩을 할 때 위치 기반, 이름 기반 두 가지를 사용할 수 있다.

  • 결론부터 말하면 이름 기반 파라미터 바인딩을 사용할 것.
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가 아니라 Collection으로 주면 모든 타입을 받을 수 있어 재활용성 증가.

😊 반환 타입

  • 스프링 데이터 JPA는 유연한 반환 타입 지원한다.
List<Member> findByUsername(String name); //컬렉션
Member findByUsername(String name); //단건
Optional<Member> findByUsername(String name); //단건 Optional

[스프링 데이터 JPA 공식 문서]

⚽ 조회 결과가 많거나 없으면 ?

🧨 컬렉션

결과가 없다면 : 빈 컬렉션(empty collection) 반환

🧨 단건 조회

  • 결과가 없다면 : null 반환
  • 결과가 2건 이상 : javax.persistence.NonUniqueResultException 예외 발생
    ❤️ 실무에서는 Optional로 반환해야해 !!
  • orElseXXX (데이터가 있을 수도 없을 수도 있는 경우)

참고

단건으로 지정한 메서드를 호출하면 스프링 데이터 JPA는 내부에서 JPQL Query.getSingleResult() 메서드를 호출한다. 이 메서드를 호출했을 때 조회 결과가 없으면 javax.persistence.NoResultException 예외가 발생하는데 개발자 입장에서 다루기가 상당히 불편하다. 스프링 데이터 JPA는 단건을 조회할 때 이 예외가 발생하면 예외를 무시하고 대신에 null 을 반환한다.

🧨 그래서 단건은 Optional !!

예외처리도 쉽고 프론트단과 얘기해서 어떤 식으로 반환해줄지 정하기도 편해서 Optional이 좋다.

@Param

@Param 어노테이션은 매핑할 때 사용하는 어노테이션이다.

  • 이렇게 @Param 어노테이션을 붙이면 본인이 원하는 이름으로 mapper에서 사용할 수 있다.
  • 즉 메서드 파라미터와 SQL 쿼리 바인딩을 돕는데 사용된다. 이 어노테이션은 메서드의 파라미터와 SQL 쿼리의 바인딩을 명시적으로 지정하여, 메서드 파라미터의 이름과 SQL 쿼리의 매개변수 이름을 일치 시킬 수 있다.

일반적으로 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 어노테이션은 메서드 파라미터와 쿼리의 매개변수를 연결하는데 사용되며, 이를 통해 명시적으로 파라미터를 바인딩하고 원하는 대로 쿼리를 작성할 수 있다 ~!

profile
back-end, 지속 성장 가능한 개발자를 향하여

0개의 댓글