CrudRepository와 JpaRepository
Spring Data JPA를 사용하면 Repository에서 JpaRepository와CrudRepository인터페이스중 한개를 선택한다.
아래로 갈 수록 저수준 모듈이며, 기능 구현이 많다.
1. CrudRepository
1) 정의
public interface AccountRepository extends CrudRepository<Account, Long> {
}
// 인터페이스가 비어 있어도, 아래의 메서드들은 호출이 가능
<S extends T> S save(S entity);
Optional<T> findById(ID id);
Iterable<T> findAll();
long count();
void deleteById(ID id);
...
- 메드를 정의하지 않아도 간단한 CRUD 사용이 가능하다
- CrudRepository는 레디스에 특화된 것은 아니고, Spring Data의 최상위 Repository 인터페이스들 중 하나
2) 문제점
우리가 정의하지 않은 기능을 인터페이스로 제공하면, 문제가 발생할 수 있다.
예를 들어,
우리는 삭제 메서드는 제공하지 않기를 바라지만,
JpaRepository 는 삭제 메서드 & 필요 없는 다른 메서드들에 대한 인터페이스도 제공한다.
2. JpaRepository
1) JpaRepository 를 상속할 경우
public interface MemverRepository extends JpaRepository<Member, Long> {
}
이미 구현되어 있는 많은 메시지가 외부에 개방된다.
→ 해당 repository에 개방된 메시지 자동완성 도움을 받았을 때, 이 repository의 책임들이 무엇이고 역할이 무엇인지 정확히 파악할 수 없게 된다.
Repository
Repository를 상속하게 되면 기본으로 구현되는 메서드가 전혀 없다. 직접 선언한 메서드에 대해서만 외부에 개방된다.
이는 Application 계층에서 Repository(Domain 계층)에 어떤 메시지를 보낼 수 있는 지 한눈에 파악할 수 있게 된다.
구현의 차이를 알아보자. JpaRepository를 상속하면 메서드를 선언하지 않아도 다양한 기능을 외부로 개방한다.
public interface AccountRepository extends JpaRepository<Account, Long> {
}
반면 Repository를 상속하면 선언한 메서드만 외부로 개방한다.
public interface AccountRepository extends Repository<Account, Long> {
void save(Account account);
Optional<Account> findById(Long id);
}
직접 선언한 메서드만 사용하므로 해당 Repository의 책임을 한 눈에 알아볼 수 있다.
그래서 JpaRepository나 CrudRepository가 아닌 Repository를 상속해서 더 깔끔한 시스템 설계를 만들 수 있다.