[Spring] Spring data jpa Projection

klmin·2024년 9월 8일

spring boot : 3.3
jdk : 21

Projection객체를 사용하면 select시 필요한 컬럼만 추출할 수 있다.

현재 Member와 Team은 N:1 관계이다.

team 테이블

52개의 데이터를 임의로 넣어놨다.

member 테이블

총 104개로 member 두개당 team을 하나씩 넣어놨다.

Member 객체

Team 객체

ManyToOne)

- Member : findAll

  • 기본적으로 제공하는 findAll 사용시 n+1 문제와 더불어 모든 컬럼을 select 하는걸 확인 할 수 있다.

- Member Repository(Dynamic Projection)

  • jpa에서는 Dynamic Projection이라고 해서 클래스 타입을 지정해서 필요한 필드만 추출할 수 있도록 제공해준다. 여러 Projection 객체를 만들어 select시에 추출하는 필드를 변경시킬 수 있다.

  • class, record, interface로 선언이 가능하며 interface 사용시에는 객체 인터페이스를 선언해 가져올 수 있지만 record나 class 사용시에는 객체는 사용하지 못하고 단일필드로만 가져올 수 있다.

- Member Interface Projection

  • 인터페이스 사용시에는 내부에 객체를 선언해서 값을 바인딩하고 가져올 수 있다. ManyToOne일경우 쿼리도 한번만 작동한다.
    member 객체는 선언된 변수만 가져오지만 내부에 객체로 선언된 team도 선언한 필드만 가져올줄 알았는데 모든 값을 가져오는걸로 보인다.
    (interface에 선언하지 않은 teamNum이 select됨)


- Member Record Projection

  • record 클래스 사용시에는 member에서 참조하고있는 객체의 명(team)을 선언하고 그 뒤에 필드명을 변수에 달아주면 값이 바인딩 된다.
    select절 조절이 가능하다.



    이런식으로 하면 맵핑이 가능하긴한데 @Query에 직접 써줘야한다.

- Memer Class Projection

  • class 선언시에는 생성자에 맵핑클래스+변수명을 선언해서 받고
    내부에 있는 변수에 매칭해서 이름을 바꿔줄 수 있다.


- Member record에 team 객체를 넣는경우



  • record나 class로 선언시에는 내부에 객체로 선언해도 값을 가져오지 못한다.

  • 인터페이스 사용시에는 프록시를 통해 JPA가 자동으로 맵핑해주는데
    class나 record 사용시에는 생성자 기반 맵핑을 사용하기 때문에
    JPQL에서 생성자를 명시적으로 호출해줘야 한다고 한다.

- Member 단건 조회

  • 필요한 필드만 select 할 수 있다.

OneToMany)

- Team : findAll

  • 기본적으로 제공하는 findAll 사용시 n+1 문제와 더불어 모든 컬럼을 select 하는걸 확인 할 수 있다.


- Team Repository

- Team Interface Projection

team interface projection 내에 실제 team 객체가 참조하는 mebers 변수로 선언해줘야 한다.
team 객체 자체는 지정된 필드만 나오지만 member는 모든게 나오고 있다.


- Team Record Projection

team 객체에서 실제로 참조하고있는 members변수를 앞에 달아줘야하고
쿼리는 한번 나오지만 list size는 member row 와 동일한 숫자로 나온다


- Team Class Projection

record 와 똑같이 member의 size만큼 team size가 생성된다.


- Team 단건 조회

team 단건 조회시 member 데이터가 여러개라 오류가 난다.


- 마무리

간단하게 Spring data jpa 사용시 Projection은 단일객체 응답 이나 ManyToOne시만 사용성이 있다고 생각이 든다.

참고 링크 : https://docs.spring.io/spring-data/jpa/reference/repositories/projections.html

profile
웹 개발자

0개의 댓글