[Spring JPA #11] 스프링 데이터 리포지터리 인터페이스 정의하기(Spring Repository Interface)
| 스프링 데이터 리포지터리 인터페이스 정의하기( Spring Data Repository Interface )
기본적으로 Spring JPA에서 제공하는 JpaRepository, CrudRepository를 사용하지만 만일 추가적인 기능을 개발하는 개발자에게 특정 메서드만 노출시킨다거나 아니면 삭제 관련 메서드(deleteAll)를 감추고 싶을 경우 Repository 인터페이스를 직접 정의할 수 있습니다.
| 리포지터리 인터페이스 예제 (@RepositoryDefinition)
프로젝트 구조
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── tutorial
│ │ │ └── springbootjpa
│ │ │ ├── Comment.java
│ │ │ ├── CommentRepository.java
│ │ │ ├── SpringBootJpaApplication.java
| | |
│ │ └── resources
│ │ ├── application.properties
│ │ ├── static
│ │ └── templates
│ └── test
│ └── java
│ └── com
│ └── tutorial
│ └── springbootjpa
│ ├── 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>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
소스 코드
@Entity
public class Comment {
@Id
@GeneratedValue
private Long id;
private String comment;
@ManyToOne
private Post post;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public Post getPost() {
return post;
}
public void setPost(Post post) {
this.post = post;
}
}
@SpringBootApplication
public class SpringBootJpaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootJpaApplication.class, args);
}
}
@RepositoryDefinition(domainClass = Comment.class, idClass = Long.class)
public interface CommentRepository {//extends MyRepository<Comment, Long>{
Comment save(Comment comment);
List<Comment> findAll();
}
- @RepositoryDefinition은 domainClass와 idClass 두 개의 파라미터를 정의해야 합니다. domainClass는 이 Repository가 인터페이스하는 엔티티-테이블이고 idClass는 이 domainClass를 식별할 때 사용하는 클래스의 타입을 뜻합니다.
- CrudRepository나 JpaRepository에 정의되어 있는 인터페이스 메서드를 참조해 메서드를 정의할 수 있습니다. 이 메서드들을 통해 엔티티와 테이블 간 상호작용을 할 수 있게 됩니다.
테스트 코드
@RunWith(SpringRunner.class)
@DataJpaTest
public class CommentRepositoryTest {
@Autowired
CommentRepository commentRepository;
@Test
public void crud() {
Comment comment = new Comment();
comment.setComment("Hello Comment");
commentRepository.save(comment);
List<Comment> all = commentRepository.findAll();
assertThat(all.size()).isEqualTo(1);
}
}
| 리포지터리 인터페이스 예제 (@NoRepositoryBean)
프로젝트 구조
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── tutorial
│ │ │ └── springbootjpa
│ │ │ ├── Comment.java
│ │ │ ├── CommentRepository.java
│ │ │ ├── MyRepository.java
│ │ │ ├── SpringBootJpaApplication.java
| | |
│ │ └── resources
│ │ ├── application.properties
│ │ ├── static
│ │ └── templates
│ └── test
│ └── java
│ └── com
│ └── tutorial
│ └── springbootjpa
│ ├── CommentRepositoryTest.java
소스 코드
@NoRepositoryBean
public interface MyRepository<T, ID extends Serializable> extends Repository<T, ID> {
<E extends T> E save(E entity);
List<T> findAll();
long count();
}
- Repository 인터페이스를 상속받아 MyRepository를 정의한 예제입니다. Repository는 특별한 기능을 제공하는 인터페이스가 아닌 마크 인터페이스입니다. 이 인터페이스가 Repository 용도로 사용될 것이라는 것을 알리는 용도로 쓰이죠.
- @NoRepositoryBean 어노테이션은 이 인터페이스가 Repository 용도로서 사용되는 것이 아닌 단지 Repository의 메서드를 정의하는 인터페이스라는 정보를 부여합니다.
- 위 예제와 마찬가지로 save, findAll 같은 메서드를 정의하면 이 메서드를 통하여 엔티티와 테이블 간에 상호작용이 일어나게 됩니다.
public interface CommentRepository extends MyRepository<Comment, Long>{
Comment save(Comment comment);
List<Comment> findAll();
}
- MyRepository 인터페이스를 상속받아 제너릭으로 정의된 인수 부분을 구체적인 엔티티와 타입명으로 정의합니다. 이 Repository 인터페이스는 Repository 용도로 쓰이는 인터페이스이며 이것을 통해 DB에 대한 작업을 소스 코드 상에서 진행할 수 있게됩니다.
테스트 코드
@RunWith(SpringRunner.class)
@DataJpaTest
public class CommentRepositoryTest {
@Autowired
CommentRepository commentRepository;
@Test
public void crud() {
Comment comment = new Comment();
comment.setComment("Hello Comment");
commentRepository.save(comment);
List<Comment> all = commentRepository.findAll();
assertThat(all.size()).isEqualTo(1);
long count = commentRepository.count();
assertThat(count).isEqualTo(1);
}
}
'Spring Data > Spring Data JPA' 카테고리의 다른 글
[Spring JPA #15] 스프링 데이터 도메인 이벤트 (0) | 2021.03.25 |
---|---|
[Spring JPA #14] 스프링 데이터 커스텀 리포지터리 만들기 (0) | 2021.03.25 |
[Spring JPA #13] 스프링 데이터 쿼리 만들기 (0) | 2021.03.25 |
[Spring JPA #12] 스프링 데이터 Null 체크 (0) | 2021.03.25 |
[Spring JPA #10] 스프링 데이터 Common 리포지터리(Repository) (0) | 2021.03.25 |
[Spring JPA #9] 스프링 데이터 JPA 원리 및 스프링 데이터 구성 요소 (0) | 2021.03.25 |
[Spring JPA #8] JPA Query (0) | 2021.03.25 |
[Spring JPA #7] JPA Fetch (0) | 2021.03.25 |