Projections

박찬우·2024년 1월 11일

스프링 데이터 JPA

목록 보기
17/18

Projections

  • 엔티티 대신에 DTO를 편리하게 조회할 때 사용 전체 엔티티가 아니라 만약 회원 이름만 딱 조회
  • 메서드 이름은 자유, 반환 타입으로 인지
  • 조회할 엔티티의 필드를 getter 형식으로 지정하면 해당 필드만 선택해서 조회(Projection)

인터페이스 기반 Closed Projections

public interface UsernameOnly {
    String getUsername();
}
List<UsernameOnly> findProjectionsByUsername(String username);

인터페이스 기반 Open Proejctions

  • 스프링의 SpEL 문법도 지원
  • SpEL문법을 사용하면, DB에서 엔티티 필드를 다 조회해온 다음에 계산한다! 따라서 JPQL SELECT 절 최적화가 안된다
public interface UsernameOnly {
    @Value("#{target.username + ' ' + target.age + ' ' + target.team.name}")
    String getUsername();
}

클래스 기반 Projection

public class UsernameOnlyDto {
    private final String username;
    public UsernameOnlyDto(String username) {
        this.username = username;
    }
    public String getUsername() {
        return username;
    }
}
List<UsernameOnlyDto> findProjectionsByUsername(@Param("username") String username);
List<UsernameOnlyDto> result = memberRepository.findProjectionsByUsername("m1");

for (UsernameOnlyDto usernameOnly : result) {
	System.out.println(usernameOnly);
}

동적 Projections

<T> List<T>  findProjectionsByUsername(@Param("username") String username,  Class<T> type);
List<UsernameOnlyDto> result = memberRepository.findProjectionsByUsername("m1", UsernameOnlyDto.class);

for (UsernameOnlyDto usernameOnly : result) {
	System.out.println(usernameOnly);
}

중첩 구조 처리

  • 프로젝션 대상이 root 엔티티면, JPQL SELECT 절 최적화 가능
  • 프로젝션 대상이 ROOT가 아니면
    • LEFT OUTER JOIN 처리
    • 모든 필드를 SELECT해서 엔티티로 조회한 다음에 계산
public interface NestedClosedProjections {
    String getUsername();
    TeamInfo getTeam();
    interface TeamInfo {
        String getName();
    }
}
List<NestedClosedProjections> result = memberRepository.findProjectionsByUsername("m1", NestedClosedProjections.class);
for (NestedClosedProjections nestedClosedProjections : result) {
	System.out.println(nestedClosedProjections);
}
profile
진짜 개발자가 되어보자

0개의 댓글