전에 공부했던 Spring Data JPA의 기본 사용법을 정리하고자 한다.
build.gradle 파일의 dependencies 부분에 다음을 추가하자.
implementation ‘org.springframework.boot:spring-boot-starter-data-jpa’
Spring Data JPA는 JpaRepository
라는 공통 인터페이스를 제공한다.
이 인터페이스는 기본적인 CRUD와 페이징 등 유용한 기능을 제공해주며, 적용하는 방법도 간단하다.
JpaRepository<T, ID>
를 상속하는 인터페이스를 구성하면 된다.
T
: 엔티티 타입ID
: 식별자 타입public interface EntityRepository extends JpaRepository<T, ID> {}
+) @Repository
애너테이션은 생략 가능하다.
컴포넌트 스캔과 JPA 예외를 스프링 예외로 변환하는 과정을 스프링 데이터 JPA가 자동으로 처리해준다.
JpaRepository가 기본적으로 제공하는 주요 메소드는 다음과 같다.
메서드 | 설명 |
---|---|
<S extends T> S save(S) | 새로운 엔티티는 저장하고, 이미 있는 엔티티는 병합한다. |
delete(T) | 엔티티 하나를 삭제한다. |
Optional<T> findById(ID) | ID로 엔티티 하나를 조회한다. |
List<T> findAll(...) | 모든 엔티티를 조회한다. 정렬(Sort)이나 페이징(Pageable) 조건을 파라미터로 제공할 수 있다. |
Spring Data JPA는 메서드의 이름으로 쿼리를 생성해준다.
우리는 JpaRepository를 상속한 인터페이스 안에 규칙에 맞게 메서드를 선언해주기만 하면 된다.
메서드 이름에 관한 규칙은 다음과 같다. (By 다음에는 필드명이 들어간다)
쿼리 종류 | 이름 규칙 |
---|---|
조회 | find...By , read...By , query...By , get...By |
COUNT | count...By 반환타입 long |
EXISTS | exists...By 반환타입 boolean |
삭제 | delete...By , remove...By |
DISTINCT | findDistinct , findMemberDistinctBy |
LIMIT | findFirst3 , findFirst , findTop , findTop3 |
🔖 이름 규칙 - 주의할 점
엔티티의 필드명이 변경되면 인터페이스에 정의한 메서드 이름도 꼭 함께 변경해야 한다.
그렇지 않으면 애플리케이션을 시작하는 시점에 오류가 발생한다.
메서드 이름에 들어가는 키워드는 다음과 같다.
Keywords | Sample | JPQL snippet |
---|---|---|
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 ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection 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) |
Pageable
, Slice
, Sort
Page<User> findByLastname(String lastname, Pageable pageable);
Slice<User> findByLastname(String lastname, Pageable pageable);
List<User> findByLastname(String lastname, Sort sort);
List<User> findByLastname(String lastname, Pageable pageable);
🔖 공식문서 참고
자세한 내용은 다음을 참고하자.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods