본문 바로가기
Study/JPA

Spring Data JPA에서 Query를 사용하는 방법

by 오늘만 사는 여자 2022. 3. 15.
728x90
반응형

Spring JPA Data Doc에서는?

 

 

https://docs.spring.io/spring-data/jpa/docs/2.3.3.RELEASE/reference/html/#jpa.repositories

 

Spring Data JPA - Reference Documentation

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

docs.spring.io

다음과 같은 방식으로 키워드만 있으면, JPA를 통해서 SQL이 자동 생성됩니다. 키워드는 다음과 같다.

 

 

KeywordSampleJPQL snippet
And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
Is, Equals findByFirstname,findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
Between findByStartDateBetween … where x.startDate between ?1 and ?2
LessThan findByAgeLessThan … where x.age < ?1
LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
GreaterThan findByAgeGreaterThan … where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
After findByStartDateAfter … where x.startDate > ?1
Before findByStartDateBefore … where x.startDate < ?1
IsNull, Null findByAge(Is)Null … where x.age is null
IsNotNull, NotNull findByAge(Is)NotNull … where x.age not null
Like findByFirstnameLike … where x.firstname like ?1
NotLike findByFirstnameNotLike … where x.firstname not like ?1
StartingWith findByFirstnameStartingWith … where x.firstname like ?1 (parameter bound with appended %)
EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (parameter bound with prepended %)
Containing findByFirstnameContaining … where x.firstname like ?1 (parameter bound wrapped in %)
OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
Not findByLastnameNot … where x.lastname <> ?1
In findByAgeIn(Collection<Age> ages) … where x.age in ?1
NotIn findByAgeNotIn(Collection<Age> ages) … where x.age not in ?1
True findByActiveTrue() … where x.active = true
False findByActiveFalse() … where x.active = false
IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstame) = UPPER(?1)

 

 

이런 예시를 통해서 아래쪽과 같이 메서드를 만들어 쓰는 방식을 통해서 서비스단에서 그 메서드를 이용하면, 스스로 쿼리를 생성하여 작동하게 된다.

 

 

@Repository에서 메소드를 만들고 나면,

@Service에서 다음과 같이 사용할 수 있다.

 

 

Query를 직접 써서 직접 메소드를 만드는 방법

 

 

물론 Spring Data JPA를 메서드 키워드를 통해서, 쿼리를 직접 만드는 방법도 있지만, 구체적인 쿼리를 작성해야 하는 경우도 있다. 사실 저런 키워드를 가지고 충분히 만드는 것도 가능하지만, 직접 쿼리를 사용하는 것도 직관적인 경우도 있다.

  1. 쿼리를 직접 쓰는 경우는 다음과 같은 조건이 있어야한다.
 
@Query("SELECT u FROM User u WHERE u.status = 1")
 
Collection<User> findAllActiveUsers();

From table 별칭을 Select문안에 넣어야 한다. 안 그러면 오류를 만들어낸다. 하지만 이런 오류를 집어내면서 해결하는 것이 은근히 귀찮다.

  1. DB에서 쓰는 것처럼 직접 쿼리를 작성하는 방식
 
@Query(
 
value = "SELECT * FROM USERS u WHERE u.status = 1",
 
nativeQuery = true)
 
Collection<User> findAllActiveUsersNative();

@Query 옵션에서 nativeQuery = true를 줘야지만... DB에서 쿼리문을 작성하는 방식으로 작성할 수도 있다.

 

 

JPA에서 메서드 Parameter를 통해서 @Query에 그 parameter가 넣어지는 방식

 

쿼리를 작성 시 파라미터를 통한 구체적 조건을 줘야 하는 경우가 종종 있다. 그러면 어떤 식으로 처리해야하는가에 대한 문제가 발생할때 다음과 같은 방법을 사용하자.

  1. ?를 통한 경우 -> parameter의 위치에 따른 숫자를 넣어주면 된다.
  2. ?1 -> parameter 첫번째 자리에 있는걸 넣겠다는 뜻.
 
public interface UserRepository extends JpaRepository<User, Long> {
 
 
 
@Query("select u from User u where u.emailAddress = ?1")
 
User findByEmailAddress(String emailAddress);
 
}

 

  1. :name -> 파라미터의 이름으로 검색하는 경우물론 @Param으로 지정해줘도 되지만, Spring 4버젼, java8 기준으로 @Param주석 없이도 파라미터의 이름 기준으로 알아서 잘 찾아준다.
  2.  
    public interface UserRepository extends JpaRepository<User, Long> {
     
     
     
    @Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
     
    User findByLastnameOrFirstname(@Param("lastname") String lastname,
     
    @Param("firstname") String firstname);
     
     
     
    @Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
     
    User findByLastnameOrFirstname(String lastname, String firstname); //이렇게도 사용 가능하다.
     
    }



출처: https://sundries-in-myidea.tistory.com/91 [얇고 넓은 개발 블로그]

728x90
반응형

댓글