2023. 1. 26. 13:19ㆍSpring
쿼리 메서드 기능 중 메서드 이름만으로 쿼리를 생성하는 기능이 있습니다. 인터페이스에 메서드만 선언하면 해당 메서드가 이름으로 적절한 JPQL 쿼리를 생성해서 실행합니다.
Spring Data JPA가 제공하는 쿼리 메소드 기능은 크게 3가지입니다.
- 메서드 이름으로 쿼리 생성
- 메서드 이름으로 JPA Named 쿼리, Named 네이티브 쿼리 호출
- @Query 어노테이션을 사용해서 리포지토리 인터페이스에 쿼리 직접 정의
@Query 어노테이션을 사용해서 리포지토리 인터페이스에 쿼리 직접 정의 하는 건 토이플젝에서 늘 하던 방식이므로
이번 포스팅에서느 메서드 이름으로 쿼리 생성에 대해 자세하게 살펴보도록 하겠습니다.
[ 메소드 이름으로 쿼리 생성 ]
토이프로젝트로 웹 애플리케이션을 만들 때 로그인 input에는 이메일과 이름을 기입해야 한다고 가정해 봅시다.
그럴 때 이메일과 이름을 조회하려면 다음과 같은 메서드를 정의하면 됩니다.
public interface UserRepository extends Repository<User, Long> {
List<User> findByEmailAndName(String email, String name);
}
findByEmailAndName()를 실행하면 Spring Data JPA는 규칙에 맞게 분석해서 적절한 JPQL을 생성하고 실행합니다.
실행된 JPQL은 다음과 같습니다.
select u from User u where u.email = ?1 and u.name =?2
메소드 이름 짓는 규칙만 잘 지켜준다면 원하는 쿼리를 자동으로 쉽게 뽑아줄 수 있습니다.
Spring Data JPA공식문서가 제공하는 표를 보면 기능을 어떻게 사용해야 하는지 알 수 있습니다.
키워드 | 예 | JPQL 예 |
Distinct | findDistinctByLastnameAndFirstname | select distinct … where x.lastname = ?1 and x.firstname = ?2 |
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.firstname) = UPPER(?1) |
[참고] Spring Data JPA공식문서
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation
여기서 주의해야 할 점은, 만약에 엔티티의 필드명이 변경되면 인터페이스에 정의한 메서드 이름도 함께 변경해주어야 합니다.
❗❗ 헷갈리는 개념 정리 ❗❗
1. custom query (JPQL 문법)
class name, field name 사용
2. native query (SQL문법)
table name, column name 사용
nativeQuery속성이 false면 JPQL, true면 SQL입니다.
@Query("SELECT m FROM Member m") // JPQL
@Query("SELECT m.* FROM Member m", nativeQuery = true) // SQL
'Spring' 카테고리의 다른 글
[Spring] gradlew: command not found 에러 (0) | 2023.03.09 |
---|---|
[타임리프] Session Id를 html, js에 가져다 쓰는 방법 (0) | 2023.02.08 |
스프링 빈 이란? 스프링 빈 등록하는 방법 (@Bean, @Configuration, @Component) (0) | 2022.11.13 |
@RequestParam과 @PathVariable 차이 (0) | 2022.11.07 |
스프링IoC 컨테이너 (Feat. 빈(Bean), 빈 스코프(Bean Scope)) (0) | 2022.10.24 |