Spring/JPA

Spring Data JPA - 파라미터 바인딩

묠니르묘묘 2022. 4. 18. 11:33

 

스프링 데이터 JPA는 다음 2가지 방법으로 파라미터 바인딩을 지원한다.

  • 위치 기반
  • 이름 기반
SELECT m FROM Member m WHERE m.username = ?0 // 위치 기반
SELECT m FROM Membeer m WHERE m.username = :name // 이름 기반

스프링 데이터 JPA의 기본값으로는 위치 기반 파라미터 바인딩을 지원한다. 이것은 파라미터 순서로 바인딩하는 것이다.

 

📝 코드 가독성과 유지보수를 위해 위치 기반보다는 이름 기반을 사용하게 된다.
위치 기반은 순서 실수가 있기 때문이다.

 

위 내용은 공식문서에서도 적혀져 있다.

By default, Spring Data JPA uses position-based parameter binding, as described in all the preceding examples.
This makes query methods a little error-prone when refactoring regarding the parameter position.
To solve this issue, you can use @Param annotation to give a method parameter a concrete name and bind the name in the query, as shown in the following example:
기본적으로 스프링 데이터 JPA는 위의 모든 예시에서 설명한 대로 위치 기반 매개변수 바인딩을 사용한다.
따라서 매개변수 위치에 대해 리팩토링 할 때 쿼리 메서드에서 약간 오류가 발생하기 쉽다.
문제를 해결하려면 다음 예시와 같이 @Param 어노테이션을 사용하여 메서드 매개변수에 구체적인 이름을 지정하고 쿼리에서 이름을 바인딩할 수 있다.

이후 이름 기반 파라미터 바인딩을 예시로 설명해주고 있다.

그렇다면 이름 기반 파라미터 바인딩은 어떻게 사용하는지 알아보자.

 

 

 

이름 기반 파라미터 바인딩 사용 예시

Spring Data Jpa
동작 순서
동작 테스트

이런 식으로 @Query를 사용해서 정의한 후 사용하면 된다.

 

 

 

🧐 어? 그런데 @Param을 안넣어도 동작해요!!!

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.named-parameters

공식문서에도 나와있는데 Java8 버전 이상부터  -parameters  라는 Compiler flag를 지원하고 있다.

이 설정으로 매개변수 이름 바인딩을 지원하게 된다. 디버그 정보의 대안으로 빌드에서 이 flag를 사용하면 @Param  을 생략할 수 있다.

 

👍 쉽게 말하자면, 자바 컴파일러에 -parameters 옵션을 설정한다면 @Param 을 생략해도 알아서 이름 바인딩을 해주는 것이다. 

 

 

 

📝 결론

Java8 이상부터는 리플렉션을 통해 메서드의 매개변수 이름에 접근할 수 있다.

이러한 방식으로 스프링이 메서드 파라미터의 이름에서 JPQL 파라미터의 이름을 추론할 수 있다.

이 때  -parameters  flag를 컴파일과 함께 사용해야한다.

만약 Java8보다 버전이 낮거나 위 옵션을 설정하지 않았다면  @Param  을 사용하여 이름을 바인딩하자.