[Spring JPA #24] Spring JPA Projection
| Spring JPA Projection
Spring JPA에서 제공하는 Projection 기능은 엔티티의 일부 데이터만을 가져오게 하는 기능입니다. Projection은 인터페이스 기반으로 구현되며 이 인터페이스를 가지고 Repository의 반환값에 명시하면 이 정보를 토대로 JPA가 해당 쿼리를 최적화해서 가져올 수 있거나 표현식을 사용하여 DB에서 데이터를 커스터마이징하여 가져올 수 있습니다.
| Spring JPA Projection 예제
프로젝트 구조
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── tutorial
│ │ │ └── springevent
│ │ │ ├── Application.java
│ │ │ ├── Comment.java
│ │ │ ├── CommentOnly.java
│ │ │ ├── CommentRepository.java
│ │ │ ├── CommentSummary.java
│ │ │ ├── PostController.java
│ │ │ ├── Post.java
│ │ │ └── PostRepository.java
│ │ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── tutorial
│ └── springevent
│ └── CommentRepositoryTest.java
의존성 관리
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
소스 코드
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Entity
@Data
public class Comment {
@Id
@GeneratedValue
private Long id;
private String comment;
@ManyToOne
private Post post;
private int up;
private int down;
private boolean best;
}
@Entity
@Data
public class Post {
@Id @GeneratedValue
private Long id;
private String title;
@Temporal(TemporalType.TIMESTAMP)
private Date created;
}
public interface CommentOnly {
String getComment();
}
- Closed 프로젝션 인터페이스로서 하나의 Comment만을 가져오게 JPA에서 최적화시킬 수 있습니다.
public interface CommentSummary {
String getComment();
int getUp();
int getDown();
default String getVotes() {
return getUp() + " " + getDown();
}
}
- Commnet, Up, Down 컬럼을 가져올 수 있고 이 두 컬럼을 조합해서 getVotes 메서드를 통해 기존값을 결합하여 데이터를 가져올 수 있습니다.
public interface CommentRepository extends JpaRepository<Comment, Long> {
<T> List<T> findByPost_Id(Long id, Class<T> type);
}
- 제네릭을 통하여 같은 메서드로 데이터를 가져오는 Projection들을 한 메서드를 통해 데이터를 가져올 수 있게 합니다.
public interface PostRepository extends JpaRepository<Post, Long> {
}
테스트 코드
@RunWith(SpringRunner.class)
@DataJpaTest
public class CommentRepositoryTest {
@Autowired
CommentRepository commentRepository;
@Autowired
PostRepository posts;
@Test
public void getComment() {
Post post = new Post();
post.setTitle("jps");
Post savedPost = posts.save(post);
Comment comment = new Comment();
comment.setComment("Hello World");
comment.setPost(savedPost);
comment.setUp(10);
comment.setDown(1);
Comment save = 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());
});
}
}
'Spring Data > Spring Data JPA' 카테고리의 다른 글
JPA 영속성 관리 - persistence context(영속성컨텍스트) (0) | 2021.04.15 |
---|---|
springframework JPA + QueryDSL (0) | 2021.04.15 |
springframework JPA 간단히 사용해보기. (0) | 2021.04.15 |
[Spring JPA #25] Spring JPA Specification (0) | 2021.03.26 |
[Spring JPA #23] Spring JPA EntityGraph (0) | 2021.03.26 |
[Spring JPA #22] Spring JPA Named Parameter, SpEL (0) | 2021.03.26 |
[Spring JPA #21] Spring JPA 쿼리 메서드 및 정렬 (0) | 2021.03.26 |
[Spring JPA #20] 스프링 부트 Spring JPA 엔티티 저장 메커니즘 (0) | 2021.03.26 |