티스토리 뷰
projections이란 쉽게 말해서 쿼리에 셀렉트 절에 들어갈 데이터(필드) 라고 보면된다고 한다.
엔티티 대신에 DTO를 편리하게 조회할 때 사용
전체 엔티티가 아니라 만약 회원 이름만 딱 조회하고 싶으면?
1. 인터페이스를 하나 만든다. 값을 얻고싶은 메소드만 만들어주기
package study.datajpa.repository;
public interface UsernameOnly {
String getUsername();
}
2. repository에는 반환형태를 인터페이스 네임으로 붙여준다
List<UsernameOnly> findProjectionByUsername(@Param("username")String username);
}
3.메소드를 사용해서 반환한다.
@Test
public void projections(){
Team teamA = new Team("teamA");
em.persist(teamA);
Member m1 = new Member("m1", 0, teamA);
Member m2 = new Member("m2", 0, teamA);
em.persist(m1);
em.persist(m2);
em.flush();
em.clear();
//when
List<UsernameOnly> result = memberRepository.findProjectionByUsername("m1");
for (UsernameOnly usernameOnly : result) {
System.out.println("usernameOnly = " + usernameOnly);
}
}
4. 로그를 확인하면 username 필드만 불러온다.
2024-03-07T13:59:46.162+09:00 DEBUG 3568 --- [ main] org.hibernate.SQL :
select
m1_0.username
from
member m1_0
where
m1_0.username=?
만약 몇개를 고르고 싶으면
package study.datajpa.repository;
import org.springframework.beans.factory.annotation.Value;
public interface UsernameOnly {
@Value("#{target.username + ' ' + target.age}")
String getUsername();
}
1. 그러면 쿼리는 모든 필드를 가져온다.
2. 작성한 필드만 가져오게 된다.
클래스 기반으로 가져오기
package study.datajpa.repository;
public class UsernameOnlyDto {
private final String username;
public UsernameOnlyDto(String username) { //생성자의 파라미터로 필드를 정한다.
this.username = username;
}
public String getUsername() {
return username;
}
}
혹은 제네릭 타입으로도 가능하다
<T> List<T> findProjectionByUsername(@Param("username")String username, Class<T> type);
//when
List<UsernameOnlyDto> result = memberRepository.findProjectionByUsername("m1", UsernameOnlyDto.class);
중첩구조로 가져오기
package study.datajpa.repository;
public interface NestedColosedProjections {
String getUsername();
TeamInfo getTeam();
interface TeamInfo{
String getName();
}
}
레퍼지토리
<T> List<T> findProjectionByUsername(@Param("username")String username, Class<T> type);
불러오기
List<NestedColosedProjections> result = memberRepository.findProjectionByUsername("m1",NestedColosedProjections.class);
로그
select
m1_0.username,
t1_0.team_id,
t1_0.name
from
member m1_0
left join
team t1_0
on t1_0.team_id=m1_0.team_id
where
m1_0.username=?
조인된 필드는 모두 가져오게 된다.
- 프로젝션 대상이 root 엔티티면, JPQL SELECT 절 최적화 가능
- 프로젝션 대상이 ROOT가 아니면
- LEFT OUTER JOIN 처리
- 모든 필드를 SELECT해서 엔티티로 조회한 다음에 계산
정리
- 프로젝션 대상이 root 엔티티면 유용하다.
- 프로젝션 대상이 root 엔티티를 넘어가면 JPQL SELECT 최적화가 안된다!
- 실무의 복잡한 쿼리를 해결하기에는 한계가 있따.
- 실무에서는 단순할 때만 사용하고, 조금만 복잡해지면 QueryDSL을 사용하자.
'dev_공부일지 > spring data JPA' 카테고리의 다른 글
네이티브 쿼리 (0) | 2024.03.07 |
---|---|
Query by Example (0) | 2024.03.07 |
Specifications(명세)(실무에서 잘 사용하지 않지만) (0) | 2024.03.06 |
data JPA 구현체 분석 (0) | 2024.03.06 |
Web 확장 - 페이징과 정렬 (0) | 2024.03.06 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 향해99
- Intercepter
- jpa api
- React
- 리터럴
- exception
- HTTP
- 향해플러스
- rejectValue
- JPA
- BindingResult
- 항해플러스
- SpringBoot
- 백엔드 개발자 역량
- reject
- 스프링공부
- 스프링부트
- 컨트
- filter
- 인터셉터
- 예외처리
- thymleaf
- hypertexttransferprotocol
- react실행
- 항해99
- 향해플러스백엔드
- Java
- ArgumentResolver
- 백엔드 개발자 공부
- 로그인
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
글 보관함