JPA 심화 3-4

5w31892p·2023년 2월 4일
0

JPA 심화

목록 보기
14/19

Projection

  • 원하는 필드만 지정해서 조회 가능
  • 여러필드 합쳐서 재정의 필드(Alias) 조회 가능 (Nested 프로젝션)
  • 조회 필드 그룹을 인터페이스 또는 클래스로 만들어놓고 재사용 가능
  • get으로 받아오기 때문에 getter 필수

:: Porjection 필드 사용방법

get필드() 메소드로 정의

  • 정의한 필드만 조회하기 때문에 Closed 프로젝션 이라고 함
  • 쿼리를 줄이므로 최적화 가능
  • 메소드 형태이기 때문에 Java 8의 메소드를 사용해서 연산
public interface UserProfile {
  String getUsername();

  String getProfileImageUrl();
}

// select username, profileImageUrl from user; // closed projection

@Value 로 정의

  • 전체 필드를 조회할 수 밖에 없어서 Open 프로젝션 이라고 함

  • @Value(SpEL)을 사용해서 연산

  • SpEL(Spring Expression Language) 가이드

  • SpEL(Spring Expression Language) 연산자

    타입연산자
    Arithmetic+, -, *, /, %, ^, div, mod
    Relational<, >, ==, !=, <=, >=, lt, gt, eq, ne, le, ge
    Logicaland, or, not, &&,
    Conditional?:
    Regexmatches
    // 연산자 사용 예시
    public interface UserProfile {
    
    @Value('#{target.profileImageUrl != null}')
    Boolean hasProfileImage;
    }
  • 스프링 빈 메서드 호출도 가능

    // 스프링 빈 메서드 호출 예시
    // workersHolder 는 bean 으로 등록한 contextHolder
    
    @Value("#{workersHolder.salaryByWorkers['George']}")
    private Integer georgeSalary;
  • 쿼리 최적화 불가

    • SpEL은 entity 대상으로 사용하기 때문

:: Projection 구현체 정의방법

  1. 인터페이스 기반 Projection

    • Projection 을 Interface 처럼

      public interface UserProfile {
      
      String getUsername();
      
      String getProfileImageUrl();
      
      @Value("#{target.profileImageUrl != null}")
      boolean hasProfileImage();
      
      default String getUserInfo() {
        return getUsername() + " " + (hasProfileImage() ?
        getProfileImageUrl() : "");
      }
      }
  2. 클래스 기반 Projection

    • Projection 을 DTO 클래스 처럼

      @Getter
      @AllArgsConstructor
      public class UserInfo {
      
      private String username;
      
      private String password;
      
      public String getUserInfo() {
        return username + " " + password;
      }
      }
  3. 다이나믹 Projection

    • Projection 클래스를 동적으로 지정해서 사용

GitHub 실습코드

0개의 댓글