스프링 데이터 JPA 8. Projection - KwangtaekJung/inflearn-spring-data-jpa-keesun GitHub Wiki
엔티티의 일부 데이터만 가져오기.
-
Nested 프로젝션 가능.
-
Closed 프로젝션
-
쿼리를 최적화 할 수 있다. 가져오려는 애트리뷰트가 뭔지 알고 있으니까.
-
Java 8의 디폴트 메소드를 사용해서 연산을 할 수 있다.
-
Comment로 조회하면 모든 컬럼을 가져온다.
List<Comment> findByPost_Id(Long id); //연관 관계인 Post의 Id로 조회 (Comment 테이블 만들때 post_id 컬럼으로 만들어 지기때문에 findByPost로는 하면 에러 발생함.)
select comment0_.id as id1_1_, comment0_.best as best2_1_, comment0_.comment as comment3_1_, comment0_.down as down4_1_, comment0_.post_id as post_id6_1_, comment0_.up as up5_1_ from comment comment0_ left outer join post post1_ on comment0_.post_id=post1_.id where post1_.id=?
- 특정 컬럼만 가져온다. 쿼리 최적화한다.
public interface CommentSummary { String getComment(); int getUp(); int getDown(); }
List<CommentSummary> findByPost_Id(Long id);
select comment0_.comment as col_0_0_, comment0_.up as col_1_0_, comment0_.down as col_2_0_ from comment comment0_ left outer join post post1_ on comment0_.post_id=post1_.id where post1_.id=?
- 쿼리 최적화도 같이 하는 방법 (default 메소드 이용한다.)
public interface CommentSummary { String getComment(); int getUp(); int getDown(); default String getVotes() { return getUp() + " " + getDown(); } }
-
-
Open 프로젝션
- @Value(SpEL)을 사용해서 연산을 할 수 있다. 스프링 빈의 메소드도 호출 가능.
- 쿼리 최적화를 할 수 없다. SpEL을 엔티티 대상으로 사용하기 때문에.
public interface CommentSummary { String getComment(); int getUp(); int getDown(); @Value("#{target.up + ' ' + target.down}") String getVotes(); }
@Test public void getComment() { Post post = new Post(); post.setTitle("jpa"); Post savedPost = postRepository.save(post); Comment comment = new Comment(); comment.setPost(savedPost); comment.setUp(10); comment.setDown(1); Comment savedComment = commentRepository.save(comment); commentRepository.findByPost_Id(savedPost.getId()).forEach(c -> { System.out.println("================"); System.out.println(c.getVotes()); }); }
select comment0_.id as id1_1_, comment0_.best as best2_1_, comment0_.comment as comment3_1_, comment0_.down as down4_1_, comment0_.post_id as post_id6_1_, comment0_.up as up5_1_ from comment comment0_ left outer join post post1_ on comment0_.post_id=post1_.id where post1_.id=?
- 이것도 Open, Close 프로젝션 모두 있음.
- DTO
- 롬복 @Value로 코드 줄일 수 있음
- 프로젝션 용 메소드 하나만 정의하고 실제 프로젝션 타입은 타입 인자로 전달하기.
<T> List<T> findByPost_Id(Long id, Class<T> type);
public interface CommentOnly {
String getComment();
}
@Test
public void getComment() {
Post post = new Post();
post.setTitle("jpa");
Post savedPost = postRepository.save(post);
Comment comment = new Comment();
comment.setComment("Spring Data Jpa");
comment.setPost(savedPost);
comment.setUp(10);
comment.setDown(1);
Comment savedComment = commentRepository.save(comment);
commentRepository.findByPost_Id(savedPost.getId(), CommentSummary.class).forEach(c -> {
System.out.println("================");
System.out.println(c.getVotes());
});
commentRepository.findByPost_Id(savedPost.getId(), CommentOnly.class).forEach(c -> {
System.out.println("================");
System.out.println(c.getComment());
});
}