DATA JPA로 query method를 생성하는 3가지 방법이 있습니다.
Method name strategy, @Query, Named Queries입니다.
마지막 방법 Named Queries로 db query 생성하는 법을 배워보겠습니다.
이전과 같이 contains와 IgnoreCase를 구현하는 db query를 생성해보겠습니다.
we have to find the answers to these questions:
How can we create named queries?
How can we create the query methods that invokes our named queries?
속성 파일, 주석 또는 orm.xml 파일을 사용하여 Spring Data JPA로 명명된 쿼리를 지정할 수 있습니다.
에서는 이러한 방법을 자세히 살펴보기 전에 명명된 쿼리의 이름을 지정할 때 따라야 하는 몇 가지 규칙을 배워야 합니다. 이러한 규칙은 다음과 같습니다:
Spring Data JPA의 기본 명명 전략을 사용하려면 entity class name 구문을 사용하여 명명된 쿼리의 이름을 지정해야 합니다.호출된 쿼리 메서드의 이름.
다른 구문을 사용하려면 명명된 쿼리를 호출하는 쿼리 메서드를 만들 때 명명된 쿼리의 이름을 구성해야 합니다. @Query 주석의 이름 속성을 사용하여 이 작업을 수행할 수 있습니다.
이제 Spring Data JPA로 명명된 쿼리를 만들 준비가 되었습니다. 먼저 명명된 쿼리를 속성 파일에 추가합니다.
속성 파일 사용
클래스 경로의 META-INF 폴더에서 찾은 jpa-name-queries.properties 파일에 추가하여 명명된 쿼리를 선언할 수 있습니다.
다른 속성 파일을 사용하거나 jpa-name-queries.properties 파일을 다른 디렉터리로 이동하려는 경우 다음 두 가지 옵션을 사용하여 위치를 구성할 수 있습니다:
Java 구성을 사용하여 응용 프로그램의 응용 프로그램 컨텍스트를 구성하는 경우 명명된 쿼리의 값을 설정하여 속성 파일의 위치를 구성할 수 있습니다@EnableJpaReposities 주석의 위치 특성입니다.
XML 구성 파일을 사용하여 응용 프로그램의 응용 프로그램 컨텍스트를 구성하는 경우 저장소 요소의 명명된 쿼리 위치 속성 값을 설정하여 속성 파일의 위치를 구성할 수 있습니다.
Example:
We want to create a named query whose name is 'Todo.findByTitleIs'. It returns all todo entries whose title is 'title'.
If we want to use JPQL, we have to add the following line into our properties file:
Todo.findByTitleIs=SELECT t FROM Todo t WHERE t.title = 'title'
If we want to use SQL, we have to add the following line into our properties file:
Todo.findByTitleIs=SELECT * FROM todos t WHERE t.title = 'title'
Let’s move on and find out how we can declare named queries by using annotations.
다음과 같은 주석으로 엔티티에 주석을 달아 명명된 쿼리를 선언할 수 있다:
JPQL 쿼리를 생성하려면 @NamedQuery 주석을 사용하여 엔티티에 주석을 달아야 합니다.
SQL 쿼리를 만들려면 @NamedNativeQuery 주석을 사용하여 엔티티에 주석을 달아야 합니다.
명명된 쿼리를 둘 이상 생성하려면 @NamedQueries 또는 @NamedNativeQueries 주석 안에서 쿼리를 정리해야 합니다.
We want to create a named query whose name is 'Todo.findByTitleIs'. It returns all todo entries whose title is 'title'.
If we want to create a JPQL query, we must follow these steps:
Annotate the entity with the @NamedQuery annotation.
Set the name of the named query (Todo.findByTitleIs) as the value of the @NamedQuery annotation’s name attribute.
Set the JPQL query (SELECT t FROM Todo t WHERE t.title = 'title') as the value of the @NamedQuery annotation’s query attribute.
@Entity @NamedQuery(name = "Todo.findByTitleIs", query = "SELECT t FROM Todo t WHERE t.title = 'title'" ) @Table(name = "todos") final class Todo { }
@NamedQueries가 아닌 @NamedQuery를 붙인다.
If we want to create a SQL query, we must follow these steps:
Annotate the entity with the @NamedNativeQuery annotation.
Set the name of the named query (Todo.findByTitleIs) as the value of the @NamedNativeQuery annotation’s name attribute.
Set the SQL query (SELECT * FROM todos t WHERE t.title = 'title') as the value of the @NamedNativeQuery annotation’s name attribute.
Set the returned entity class (Todo.class) as the value of the of the @NamedNativeQuery annotation’s resultClass attribute.
``
@Entity
@NamedNativeQuery(name = "Todo.findByTitleIs”,
query="SELECT * FROM todos t WHERE t.title = 'title'",
resultClass = Todo.class
)
@Table(name = "todos")
final class Todo {
}
``
We can declare named queries by adding them into the orm.xml file that is found from the META-INF folder of our classpath. We have to use one of these two XML elements:
If we want to create a JPQL query, we have to use the named-query element.
If we want to create a SQL query, we have to use the named-native-query element
We want to create a named query whose name is 'Todo.findByTitleIs'. It returns all todo entries whose title is 'title'.
If we want to create a JPQL query, we must follow these steps:
Add a named-query element into the orm.xml file.
Set the name of the named query (Todo.findByTitleIs) as the value of the named-query element’s name attribute.
Add a query element as the child of the named-query element and set the invoked JPQL query (SELECT t FROM Todo t WHERE t.title = 'title') as the value of the query element.
``
<named-query name="Todo.findByTitleIs">
<query>SELECT t FROM Todo t WHERE t.title = 'title'</query>
</named-query>
``
If we want to create a SQL query, we must follow these steps:
Add a named-native-query element to the orm.xml file.
Set the name of the named query (Todo.findByTitleIs) as the value of the named-native-query element’s name attribute.
Set the type of the returned object (net.petrikainulainen.springdata.jpa.todo.Todo) as the value of the named-native-query element’s result-class attribute.
Add a query element as the child of the named-native-query element and set the invoked SQL query (SELECT * FROM todos t WHERE t.title = 'title') as the value of the query element.
``
<named-native-query name="Todo.findByTitleIs"
result-class="net.petrikainulainen.springdata.jpa.todo.Todo">
<query>SELECT * FROM todos t WHERE t.title = 'title'</query>
</named-native-query>
``
If you need to create complex SQL queries, you might have to map the results of your SQL query by using the sql-result-set-mapping element. If you want to get more information about SQL result set mapping, you should read these blog posts:
We can create the query method that invokes a specific named query by following these steps:
Add a query method into our repository interface and follow these rules:
If our named query uses the default naming strategy of Spring Data JPA, we must ensure that the name of the query method identifies the invoked named query.
If our named query doesn’t use the default naming strategy, we have to annotate the query method with the @Query annotation and configure the name of invoked named query by using the name attribute of the @Query annotation.
If the invoked named query is a SQL query, we have to annotate the query method with the @Query annotation and set the value of its nativeQuery attribute to true.
Add the correct method parameters to the query method.
Specify the return type of the query method.
We want to create a query method that invokes the named query whose name is: Todo.findByTitleIs. Because this named query returns todo entries whose title is 'title', it doesn't have any parameters.
If the invoked named query is a JPQL query, we have to add the following query method into our repository interface:
``
interface TodoRepository extends Repository<Todo, Long> {
public List<Todo> findByTitleIs();
}
``
If the invoked named query is a SQL query, we have to add the following query method into our repository interface:
``
interface TodoRepository extends Repository<Todo, Long> {
@Query(nativeQuery = true)
public List<Todo> findByTitleIs();
}
``