프로젝트 개발에 사용한 것을 정리한다.
Spring Data JPA를 사용하면 일반적으로 Repository에서 아래 인터페이스 중 하나를 상속하여 사용하게 된다.
- JpaRepository
- CrudRepository
- Repository
JpaRepository
아래로 갈수록 저수준 모듈이며, 기능 구현이 많다.
예를 들어, CurdRepository의 경우 메서드를 정의하지 않아도 간단한 CURD 사용이 가능하다.
public interface MemberRepository extends CrudRepository<Member, Long> {
}
해당 인터페이스가 비어 있어도 CrudRepository 인터페이스를 상속받기 때문에 아래의 메서드들을 호출할 수 있다.
- save()
- findById()
- findAlll()
- count()
- deleteById()
- ...
JpaRepository에서는 간단한 CURD 이외에도 Paging 관련 기능, Batch 사용 등 더 많은 기능을 상속받아 사용할 수 있다.
Repository
Repository를 상속하게 되면 기본으로 구현되는 메서드가 전혀 없다.
즉, 직접 선언한 메서드에 대해서만 외부에 개방된다.
이는 Application 계층에서 Repository(Domain 계층)에 어떤 메서드를 선언하지 않아도 다양한 기능을 외부로 개방한다.
public interface MemberRepository extends JpaRepository<Member, Long> {
}
JpaRepository를 상속하면 메서드를 선언하지 않아도 다양한 기능을 외부로 개발한다.
public interface MemberRepository extends Repository<Member, Long> {
void save(Member member);
Optional<Member> findById(Long id);
}
Repository를 상속하면 선언한 메서드만 외부로 개방한다.
즉, 직접 선언한 메서드만 사용하므로 해당 Repository의 책임을 한눈에 알아볼 수 있다.
정리
JpaRepository를 사용하면 아무래도 기능이 많아서 개발할 때 편리함을 느낄 수 있을 것 같다.
하지만 정의하지 않은 기능을 인터페이스로 제공하면 문제가 발생할 수 있다.
예를 들어, 삭제 메서드는 제공하지 않고 싶을 때 JpaRepository는 삭제 메서드를 제공하고 필요 없는 다른 메서드들에 대한 인터페이스도 제공한다.
반면에 Repository를 사용할 경우, 추가로 필요한 메서드만 만들어서 사용하면 인터페이스로 제공하는 메서드 수가 훨씬 적어지고, 메서드의 재사용성도 높아진다. 이는 쿼리 캐싱에 성공할 확률이 높아지는 효과를 가져올 수 있다.
따라서 JpaRepository나 CrudRepository가 아닌 Repository를 상속하여 사용하면 더 깔끔한 시스템 설계를 만들 수 있을 것이다.
References
https://jaehoney.tistory.com/250