[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());
});
}
}


https://www.inflearn.com/course/스프링-데이터-jpa


이 글을 공유하기

댓글(0)

Designed by JB FACTORY