소스
https://github.com/rkwhr0010/jpa
스프링 데이터 JPA 소개
리포지토리 계층의 반복되는 DB 데이터 접근과 CRUD 코드를 해결해준다.
인터페이스만 작성하면 애플리케이션 실행 시점에 스프링 데이터 JPA가 구현 객체를 동적으로 생성해준다.
적절한 타입 파라미터만 넣어주면 된다.
JpaRepository 인터페이스에 없는 메서드도 스프링 데이터 JPA가 메소드 이름을 분석해 JPQL을 생성해준다.
스프링 데이터 프로젝트
스프링 데이터 프로젝트는 다양한 데이터 저장소에 대한 접근을 추상화했다
스프링 데이터 JPA는 JPA에 특화된 기능을 제공한다.
공통 인터페이스 기능
가장 간단한 방법은 JpaRepository를 구현하면된다.
T는 반환 엔티티 타입, ID는 식별자 타입이다.
쿼리 메소드 기능
메소드 이름만으로 쿼리를 생성하는 기능
인터페이스에 메소드만 선언하면, 메소드 이름 기반으로 JPQL 쿼리가 생성되고 실행된다.
메소드 이름으로 쿼리 생성
Keyword | 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<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) |
Table 1. Supported keywords inside method names
출처: <https://docs.spring.io/spring-data/jpa/reference/jpa/query-methods.html>
JPA NamedQuery
xml이나 애노테이션으로 쿼리를 정의
이렇게 호출하면 된다.
스프링 데이터 JPA는 "도메인클래스.메소드이름"으로 쿼리를 찾아 실행한다.
@Param은 이름기반 파라미터를 바인딩하는 애노테이션이다
JPA를 직접 사용했다면, 아래와 같이 사용한다.
@Query 리포지토리 메소드에 쿼리 정의
JPQL
JPQL을 1부터 시작
Native SQL
0부터 시작한다.
파라미터 바인딩
이름 기반, 위치 기반 모두 지원하지만 가급적 이름 기반 파라미터를 사용하는 것이 좋다.
벌크성 수정 쿼리
반환 타입
메서드 이름은 그대로 두고, 반환 타입만으로 유연하게 설정할 수 있다.
List<Entity> 면 한 건 이상, Entity 단 건
0 건 시 빈 컬렉션, null을 각각 반환한다.
단, 단 건을 기대하고 반환타입을 지정했는데 두 건 이상인 경우는 예외가 발생한다.
NonUniqueResultException
페이징과 정렬
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, Sort sort, Limit limit);
List<User> findByLastname(String lastname, Pageable pageable);
힌트
주의할 것은 SQL 힌트가 아닌 JPA에게 힌트를 주는 것
'개발 > JPA' 카테고리의 다른 글
13 웹 애플리케이션과 영속성 관리 (1) | 2024.06.10 |
---|---|
10 객체지향 쿼리 언어 (0) | 2024.05.27 |
09 값 타입 (0) | 2024.05.20 |
08 프록시와 연관관계 관리 (1) | 2024.05.13 |
07 고급 매핑 (0) | 2024.05.06 |