스프링데이터JPA는 인터페이스만 정의해주고, 구현체는 스프링이 자동생성해준다.
우리가 직접 구현체를 만들려면 어떻게 해야 될까?
보통 쿼리DSL을 작성할 때, 많이 사용한다고 한다.
public interface CustomMemberRepository {
List<Member> callCustom(); // 커스텀 메소드
...
}
@RequiredArgsConstructor
public class MemberRepositoryImpl implements CustomMemberRepository {
private final EntityManager em;
@Override
public List<Member> callCustom() {
return em.createQuery("select m from Member m", Member.class)
.getResultList();
}
}
JPA 레포지토리 이름 + Impl
네이밍 규칙을 지켜야한다.public interface MemberRepository extends JpaRepository<Member, Long>, CustomMemberRepository {
...
}
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
List<Member> findAll(){
return memberRepository.callCustom(); // Custom 구현체 사용
}
}
[1] CustomMemberRepository (interface) // 커스텀 Interface
└─ callCustom()
▲
[2] MemberRepositoryImpl (implements CustomMemberRepository) // 커스텀 구현체
└─ EntityManager로 JPQL 실행
▲
[3] MemberRepository (interface) // JPA 레포지토리에 상속
└─ extends JpaRepository + CustomMemberRepository
▲
[4] MemberService // 서비스 단에서 JPA 레포지토리만으로 커스텀 구현체 사용
└─ memberRepository.callCustom() 호출
핵심로직과 아닌 로직을 클래스로 분리하는 것이 복잡성을 떨어트리는데에 더 좋다.
꼭 해당도구를 사용해서 관련된 모든 문제를 해결하려고 하지 않도록 주의하자.