method name strategy로 생성한 db query를 @Query로 구현해보자.
@Query는 JPQL과 SQL queries를 둘다 지원합니다.
@Query를 붙여 생성하는 db query는 다른 모든 생성 전략보다 우선합니다.
``
interface TodoRepository extends Repository<Todo, Long> {
@Query("SELECT t FROM Todo t WHERE t.title = 'title'")
public List<Todo> findById();
}
``
해당 query method는 @Query가 붙어있으므로, method name strategy로 생성하는 query를 무시하고, @Query 로 생성한 query를 호출합니다.
JPQL 과 SQL 생성하는 법
@Query(value = "SELECT * FROM todos t WHERE t.title = 'title'",
nativeQuery=true
)
public List<Todo> findByTitle();}case 구별하지 않고, description or title이 term을 포함하는 entries를 반환하는 query를 생성하는 Function을 구현해봅시다.
@Query("select t from todo t where t.title like %:term% or t.description like %:term%")
List<todo.> findByTerm(@Param("term") String term);
named parameter의 name을 지정한 @Param을 method parameter에 붙인다.
contains 와 ignoreCase를 구현하기 위해 다음과 같이 query를 생성한다.
``
interface TodoRepository extends Repository<Todo, Long> {
@Query("SELECT t FROM Todo t WHERE " +
"LOWER(t.title) LIKE LOWER(CONCAT('%',:searchTerm, '%')) OR " +
"LOWER(t.description) LIKE LOWER(CONCAT('%',:searchTerm, '%'))")
List<Todo> findBySearchTerm(@Param("searchTerm") String searchTerm);
}
``
ignore case는 db에 있는 값을 Lower로 다 소문자로 바꾼다.
``
interface TodoRepository extends Repository<Todo, Long> {
@Query(value = "SELECT * FROM todos t WHERE " +
"LOWER(t.title) LIKE LOWER(CONCAT('%',:searchTerm, '%')) OR " +
"LOWER(t.description) LIKE LOWER(CONCAT('%',:searchTerm, '%'))",
nativeQuery = true
)
List<Todo> findBySearchTermNative(@Param("searchTerm") String searchTerm);
}
``
nativeQuery = true로 지정하고, JPQL대신 SQL로 작성하여 @Query의 value로 넣어준다.
CONCAT()은 합쳐진 String을 return
LOWER()은 argumetn의 lowercase를 return
장점
JPQL과 SQL을 지원합니다.
호출되는 query가 무엇인지 query method위에서 알 수 있습니다.
SQL을 알면 naming convention을 몰라도 구현할 수 있습니다.
단점
동적 쿼리를 지원하지 않습니다.
sQL queries를 사용할때, SQL queries가 기대한대로 동작하는지 테스트하지 않고서는 사용되는 db를 바꿀 수 없습니다.
method name strategy 보다 읽거나 쓰기 어렵지만 중요한 장점을 가집니다.
1. query method위에 invoked query를 볼 수 있습니다.
2. method name이 길지 않아 query method를 사용하는 code의 가독성이 좋습니다.