인프런 - 실전! 스프링 데이터 JPA
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
엔티티 대신에 DTO를 편리하게 조회할 때 사용
전체 엔티티가 아닌 회원 이름만 조회하고 싶다면?
1. 인터페이스 작성
2. 스프링 데이터 JPA 인터페이스 구현
- 반환타입으로 1번에서 만든 인터페이스 적용
3. 테스트
- username 만 조회해옴
- findByUsername 등과 혼용하여 사용할 수 있다. 반환타입만 지정
인터페이스 기반 Closed Projections
- 프로퍼티 형식(getter)의 인터페이스를 제공하면, 구현체는 스프링 데이터 JPA가 제공
- 정확하게 한컬럼과 매칭
public interface UsernameOnly {
String getUsername();
}
인터페이스 기반 Open Proejctions
- 다음과 같이 스프링의 SpEL 문법도 지원
- 단! 이렇게 SpEL문법을 사용하면, DB에서 엔티티 필드를 다 조회해온 다음에 계산한다! 따라서 JPQL SELECT 절 최적화가 안된다.
- Concat 과 비슷한 기능인듯
public interface UsernameOnly {
@Value("#{target.username + ' ' + target.age + ' ' + target.team.name}")
String getUsername();
}
클래스 기반 Projection
1. Dto 생성
- Dto 의 생성자 파라미터 명을 보고 Select 해온다.
2. 스프링 데이터 JPA 인터페이스 구현
- 반환타입으로 1번에서 만든 Dto 적용
3. 테스트
동적 Projections
- 다음과 같이 Generic type을 주면, 동적으로 프로젝션 데이터 번경 가능
<T> List<T> findProjectionsByUsername(String username, Class<T> type);
List<UsernameOnly> result = memberRepository.findProjectionsByUsername("m1",
UsernameOnly.class);
중첩 구조 처리
1. 중첩 인터페이스 생성
2. 스프링 데이터 JPA 인터페이스 구현
- 반환타입으로 1번에서 만든 인터페이스 적용
3. 테스트
- 중첩 구조에서, 첫번 째는 정확하게 최적화가 되지만, 두번째부터는 최적화가 되지 않음
- 프로젝션 대상이 root 엔티티면, JPQL SELECT 절 최적화 가능
- 프로젝션 대상이 ROOT가 아니면, LEFT OUTER JOIN 처리, 모든 필드를 SELECT해서 엔티티로 조회한 다음에 계산
결론
* 프로젝션 대상이 root 엔티티면 유용하다.
* 프로젝션 대상이 root 엔티티를 넘어가면 JPQL SELECT 최적화가 안된다!
* 실무의 복잡한 쿼리를 해결하기에는 한계가 있다
* 실무에서는 단순할 때만 사용하고, 조금만 복잡해지면 QueryDSL을 사용하자
'Back-end > Spring Data Jpa' 카테고리의 다른 글
나머지 기능들 - 네이티브 쿼리 (0) | 2021.06.08 |
---|---|
나머지 기능들 - Query By Example (0) | 2021.06.08 |
나머지 기능들 - Specifications (명세) (0) | 2021.06.08 |
스프링 데이터 JPA 분석 (0) | 2021.06.08 |
확장 기능 - Web 확장 (0) | 2021.06.07 |