티스토리 뷰

인프런수업/JPA

JPA Repository - Query Method

날따라해봐요요롷게 2022. 5. 11. 22:25

일반 CRUD Repository와 다르게 JPA Repository의 차이는 무엇일까?

 

그리고 JPA Repository 가 제공하는 쿼리 메소드는 일반적으로 우리가 사용하는 쿼리와 어떤 차이가 있는것일까?


Working with Spring Data Repositories
The goal of the Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.

Spring Data Repositories를 사용하는 이유 

Spring Data repository abstraction의 목표는 다양한 지속성 저장소에 대한 데이터 액세스 계층을 구현하는 데 필요한 보일러 플레이트 코드의 양을 크게 줄이는 것입니다.

보일러플레이트란?

컴퓨터 프로그래밍에서 보일러플레이트 코드라고 부르는 것은 최소한의 변경으로 여러곳에서 재사용되며, 반복적으로 비슷한 형태를 띄는 코드를 말한다.

개발자들에게 불필요하고 복잡하고 도움이 안 되는 반복적인 일들을 하지 않도록 도와주는 것이 보일러 플레이트입니다.


쿼리 메소드 사용하기

 

문서를 차근 차근 읽어보자

 

Although that is a good start, that doesn't help us to write real life applications because we have no idea how we can query information from the database by using custom search criteria.

(우리는 사용자 지정 검색 기준을 사용하여 데이터베이스에서 정보를 쿼리하는 방법을 모르기 때문에 실제 응용 프로그램을 작성하는 데 도움이 되지 않는다.) -> jpa를 사용해도 데이터 접근을 위한 검색 criteria를 모르기 때문에 제대로 사용을 하는 것이 아니라는 말이다.

 

One way to find information from the database is to use query methods. However, before we can create custom database queries with query methods, we have to find the answers to the following questions:

(데이터베이스에서 정보를 찾는 한 가지 방법은 쿼리 방법을 사용하는 것입니다. 그러나 쿼리 방법으로 사용자 정의 데이터베이스 쿼리를 만들려면 다음 질문에 대한 답을 찾아야 합니다.)

 

  • What are query methods? : 쿼리 메소드가 무엇인가?
  • What kind of return values can we use? : 우리가 사용할 반환값은 무엇인가?
  • How can we pass parameters to our query methods? : 쿼리 메소드에 파리미터를 어떻게 던질 수 있는가?

 

What are query methods?

 

Query methods are methods that find information from the database and are declared on the repository interface. For example, if we want to create a database query that finds the Todo object that has a specific id, we can create the query method by adding the findById() method to the TodoRepository interface. After we have done this, our repository interface looks as follows:

Query methods는 데이터베이스에서 정보를 찾고 repository interface에 선언되는 methods입니다.

예를 들어 특정 ID를 가진 Todo 개체를 찾는 데이터베이스 쿼리를 만들려면 findById() 메서드를 TodoRepository 인터페이스에 추가하여 쿼리 메서드를 만들 수 있습니다. 이렇게 하면 리포지토리 인터페이스는 다음과 같습니다.

import org.springframework.data.repository.Repository;
 
interface TodoRepository extends Repository<Todo, Long> { 
 
    //This is a query method.
    Todo findById(Long id);
}

 

What kind of return values can we use?

 

A query method can return only one result or more than one result. Also, we can create a query method that is invoked asynchronously. This section addresses each of these situations and describes what kind of return values we can use in each situation.

A query method는 하나의 결과만 반환하거나 둘 이상의 결과를 반환할 수 있습니다.

또한, 우리는 비동기적으로 호출되는 쿼리 방법을 만들 수 있다. 이 섹션에서는 이러한 각 상황에 대해 설명하고 각 상황에서 사용할 수 있는 반환 값의 종류를 설명합니다.

 

First, if we are writing a query that should return only one result, we can return the following types:

- Basic type. Our query method will return the found basic type or null.

: 기본 타입의 경우 기본타입, null 을 반환한다.

- Entity. Our query method will return an entity object or null.

: 엔티티의 경우 엔티티, null을 반환한다.

- Java 8 Optional<T>. Our query method will return an Optional that contains the found object or an empty Optional.

: Optional의 경우 Optional을 반환한다. (Optional은 찾고자 하는 객체, 비어있는 객체를 말한다.)

interface TodoRepository extends Repository<Todo, Long> { 
 
    @Query("SELECT t.title FROM Todo t where t.id = :id") 
    String findTitleById(@Param("id") Long id);
     
    @Query("SELECT t.title FROM Todo t where t.id = :id") 
    Optional<String> findTitleById(@Param("id") Long id);
 
    Todo findById(Long id);
     
    Optional<Todo> findById(Long id);
}

 

Second, if we are writing a query method that should return more than one result, we can return the following types : 2개 이상의 반환값이 있는 경우

- List<T>. Our query method will return a list that contains the query results or an empty list.

List 형태의 반환값 받기 : 쿼리가 원하는 결과를 리스트 형태로, 비어있는 리스트를 갖는 리스트를 반환한다.

- Stream<T>. Our query method will return a Stream that can be used to access the query results or an empty Stream.

: 스트림의 경우 . 쿼리가 원하는 결과를 스트림 형태로, 비어있는 stream을 stream 형태로 반환한다.

interface TodoRepository extends Repository<Todo, Long> { 
    List<Todo> findByTitle(String title);
    Stream<Todo> findByTitle(String title);
}

Third, if we want that our query method is executed asynchronously, we have to annotate it with the @Async annotation and return a Future<T> object.

: 셋째, 쿼리 메서드를 비동기식으로 실행하려면 @Async 주석으로 주석을 달고 <T> 객체를 반환해야 합니다.

interface TodoRepository extends Repository<Todo, Long> { 
 
    @Async
    @Query("SELECT t.title FROM Todo t where t.id = :id") 
    Future<String> findTitleById(@Param("id") Long id);
     
    @Async
    @Query("SELECT t.title FROM Todo t where t.id = :id") 
    Future<Optional<String>> findTitleById(@Param("id") Long id);
 
    @Async
    Future<Todo> findById(Long id);
     
    @Async
    Future<Optional<Todo>> findById(Long id);
 
    @Async
    Future<List<Todo>> findByTitle(String title);
     
    @Async
    Future<Stream<Todo>> findByTitle(String title);
}

세 번째 부분은 비동기식 방식을 말하는데 무얼 말하는지 잘 모르겠다.

 

 

 

How can we pass parameters to our query methods?

 

We can pass parameters to our database queries by passing method parameters to our query methods.

Spring Data JPA supports both position based parameter binding and named parameters.

쿼리 메서드에 메서드 매개 변수를 전달하여 데이터베이스 쿼리에 매개 변수를 전달할 수 있습니다.

스프링 데이터 JPA는 위치 기반 파라미터 바인딩과 명명된 파라미터를 모두 지원합니다. 

The position based parameter binding means that the order of our method parameters decides which placeholders are replaced with them. In other words, the first placeholder is replaced with the first method parameter, the second placeholder is replaced with the second method parameter, and so on.

위치 기반 매개 변수 바인딩은 우리의 방법 매개 변수의 순서에 따라 어떤 자리 표시자를 바꿀지 결정한다는 것을 의미한다. 즉, 첫 번째 자리 표시자는 첫 번째 메서드 매개 변수로 교체되고, 두 번째 자리 표시자는 두 번째 메서드 매개 변수로 교체됩니다.

 

interface TodoRepository extends Repository<Todo, Long> { 
 
    public Optional<Todo> findByTitleAndDescription(String title, String description);
     
    @Query("SELECT t FROM Todo t where t.title = ?1 AND t.description = ?2")
    public Optional<Todo> findByTitleAndDescription(String title, String description);
     
    @Query(value = "SELECT * FROM todos t where t.title = ?0 AND t.description = ?1", 
        nativeQuery=true
    )
    public Optional<Todo> findByTitleAndDescription(String title, String description);
}

 

position based parameter binding 의 문제점을 해결하는 방법 -> named parameters

 

Using position based parameter binding is a bit error prone because we cannot change the order of the method parameters or the order of the placeholders without breaking our database query. We can solve this problem by using named parameters.

위치 기반 매개 변수 바인딩을 사용하는 것은 데이터베이스 쿼리를 위반하지 않고 메서드 매개 변수의 순서나 자리 표시자의 순서를 변경할 수 없기 때문에 약간 오류가 발생하기 쉽다. 우리는 명명된 매개 변수를 사용하여 이 문제를 해결할 수 있다.

We can use named parameters by replacing the numeric placeholders found from our database queries with concrete parameter names, and annotating our method parameters with the @Param annotation.

데이터베이스 쿼리에서 찾은 숫자 자리 표시자를 구체적인 매개 변수 이름으로 바꾸고 메서드 매개 변수에 @Param 주석을 달아 명명된 매개 변수를 사용할 수 있다.

The @Param annotation configures the name of the named parameter that is replaced with the value of the method parameter.

@Param 주석은 메서드 매개 변수의 값으로 대체되는 명명된 매개 변수의 이름을 구성합니다.

 

interface TodoRepository extends Repository<Todo, Long> { 
     
    @Query("SELECT t FROM Todo t where t.title = :title AND t.description = :description")
    public Optional<Todo> findByTitleAndDescription(@Param("title") String title, 
                                                    @Param("description") String description);
     
    @Query(
        value = "SELECT * FROM todos t where t.title = :title AND t.description = :description", 
        nativeQuery=true
    )
    public Optional<Todo> findByTitleAndDescription(@Param("title") String title, 
                                                    @Param("description") String description);
}

 

요약 : 3가지

  • Query methods are methods that find information from the database and are declared on the repository interface.

쿼리 메소드는 db 데이터에 접근하기 위한 메소드이며 repository 인터페이스에 선언된다.

  • Spring Data has pretty versatile support for different return values that we can leverage when we are adding query methods to our Spring Data JPA repositories.

 

  • We can pass parameters to our database queries by using either position based parameter binding or named parameters.

출처 : https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories

 

Spring Data JPA - Reference Documentation

Example 109. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del

docs.spring.io

https://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-introduction-to-query-methods/

 

Spring Data JPA Tutorial: Introduction to Query Methods

Spring Data JPA Tutorial: Introduction to Query Methods Earlier we created our first Spring Data JPA repository that provides CRUD operations for todo entries. Although that is a good start, that doesn't help us to write real life applications because we h

www.petrikainulainen.net

 

'인프런수업 > JPA' 카테고리의 다른 글

JPA 기본  (0) 2022.05.13
h2  (0) 2022.04.25
연속성 컨텍스트  (0) 2022.04.22
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함