kkkkkkkkkkkk
kkkkk
kkkkkkkkkkkk
전체 방문자
오늘
어제
  • 분류 전체보기
    • CS & OS
    • Algorithms
    • Laguage
    • Book
      • 객체지향의 사실과 오해
      • Effective Java
      • Spring boot 와 AWS로 혼자 구현하는 ..
      • 도메인 주도 계발 시작하기
    • DB
    • Spring
    • Spring Boot
    • JPA
    • Git
    • Clean Code
    • HTTP

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 역할
  • 책임
  • 응집도
  • 결합도
  • 객체지향 프로그래밍
  • 설계 원칙

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
kkkkkkkkkkkk

kkkkk

[Jpa] Projections
JPA

[Jpa] Projections

2022. 7. 18. 18:05

아래와 같은 엔티티의 조회 시도를 하려고 한다. select 문을 날리면 해당 엔티티의 속성들이 모두 조회가 될 것이다.

 

속성들이 이보다 더 많다면 아마 성능에 문제가 되지 않을까 싶다.

그래서 해당 속성만 뽑아내려고 시도 해봤다.

public class Post {

    private Long id;
    private String userName;
    private String title;
    private String description;
    private LocalDateTime createDateTime;
    private LocalDateTime updateDateTime;
}

 

당연히 받는 타입은 PostDto로 title 과 description 만 받게 해 놓았다.

@Query("select p.title, p.description " +
        "from Post p " +
        "where p.userName =:userName")
List<PostDto> findByName(@Param("userName") String userName);

 

 

데이터가 mapping이 제대로 되지 않아 아래와 같은 에러가 발생한다.

 

상속한 JpaRepository의 제네릭 타입인 Post 타입에 대한 mapping이 되어야 한다.

 

에러를 찾아 본 결과 jpa projections 으로 해결을 해야했다.

 

참조 : https://www.baeldung.com/spring-data-jpa-projections

 

Spring Data JPA Projections | Baeldung

A quick and practical overview of Spring Data JPA Projections.

www.baeldung.com

 

dto 클래스 활용

jpql 을 작성할 때 해당 dto의 new 인스턴스를 사용하여 쿼리를 동작하게 한다.

@Query("select new " +
        "com.study.boardsystem.web.dto.PostDto(p.title, p.description) " +
        "from Post p " +
        "where p.userName =:userName")
List<PostView> findByName(@Param("userName") String userName);

이때 해당 dto 의 생성자를 사용하여 mapping을 한다. 생성자의 매개변수 이름이 루트 엔티티 클래스의 속성과 일치해야 한다.

 

인터페이스 활용

루트 엔티티 속성의 getter 메서드 명과 같게 생성한다.

public interface PostView {
    public String getTitle();
    public String getDescription();
}

다음으로 jpql 을 작성한다. alias로 루트 엔티티와 mapping 되는 정보를 명시 해줘야 한다.

@Query("select p.title as title, p.description as description " +
        "from Post p " +
        "where p.userName =:userName")
List<PostView> findByName(@Param("userName") String userName);

런타임에 PostView 타입의 프록시 인스턴스를 생성하고 여기에 정의된 메서드를 호출하여 실제 타겟 객체에 전파하게 된다.

 

참조: https://realrain.net/post/spring-projection/

 

Spring Data JPA Projections

입사 후 당장 리소스가 필요한 부분이 프론트엔드 작업이었기에 작년에는 주로 자바스크립트와 리액트를 이용한 프론트 개발을 주로 했지만, 얼마 전부터 드디어 스프링 부트를 통해 서버개발

realrain.net

 

인터페이스는 Projection을 할 때에만 사용하고 dto 클래스는 언제든 데이터를 옮길 때 사용가능 하니 dto 클래스를 사용하여 인스턴스를 생성하는 것이 좋을 것 같다라는 생각이 든다.

'JPA' 카테고리의 다른 글

[Jpa] Transaction Propagation  (0) 2022.08.06
[Jpa] Transaction Scope and Isolation  (0) 2022.08.05
[Jpa] Deprecated 된 getById() 대안 getReferenceById()  (0) 2022.08.02
[Jpa] Dirty Checking  (0) 2022.07.19
[Spring JPA] 트랜잭션은 언체크, 체크 예외에 대해 어떻게 커밋과 롤백을 처리할까?  (1) 2022.05.18
[Spring JPA] CASCADE 는 무엇일까?  (0) 2022.05.15
[Spring JPA] N + 1의 문제점이 무엇이고 어떻게 해결 해야할까?  (0) 2022.05.15
[Spring JPA] 프록시 객체는 어떻게 동작할까?  (0) 2022.05.12
    'JPA' 카테고리의 다른 글
    • [Jpa] Deprecated 된 getById() 대안 getReferenceById()
    • [Jpa] Dirty Checking
    • [Spring JPA] 트랜잭션은 언체크, 체크 예외에 대해 어떻게 커밋과 롤백을 처리할까?
    • [Spring JPA] CASCADE 는 무엇일까?
    kkkkkkkkkkkk
    kkkkkkkkkkkk

    티스토리툴바