사용자 정의 Repository 구현이 필요한 이유
- 스프링 데이터 JPA 리포지토리는 인터페이스만 정의하고 구현체는 스프링이 자동 생성한다.
- 메서드를 직접 구현해야 할 때도 있다.
- JPA 직접 사용 (EntityManager)
- 스프링 JDBC Template 사용
- MyBatis 사용
- 데이터베이스 커넥션 직접 사용
- Querydsl 사용
- 하지만 스프링 데이터 JPA가 제공하는 인터페이스를 직접 구현하면 구현해야 하는 기능이 너무 많다.
- Spring Data JPA는 필요한 메서드만 구현할 수 있는 방법을 제공한다.
- 다양한 이유로 인터페이스의 메서드를 직접 구현하고 싶다면?
사용자 정의 Repository 구현
(1) 사용자 정의 인터페이스 구현
public interface MemberRepositoryCustom {
List<Member> findMemberCustom();
}
- 인터페이스 이름은 자유롭게 지으면 된다.
(2) 사용자 정의 인터페이스 구현 클래스
@RequiredArgsConstructor
public class MemberRepositoryImpl implements MemberRepositoryCustom {
private final EntityManager em;
@Override
public List<Member> findMemberCustom() {
return em.createQuery("select m from Member m")
.getResultList();
}
}
- 규칙 : 리포지토리 인터페이스 이름 + Impl
- 스프링 데이터 JPA가 인식해서 스프링 빈으로 등록한다.
(3) 사용자 정의 인터페이스 상속
public interface MemberRepository
extends JpaRepository<Member, Long>, MemberRepositoryCustom {
}
- Repository 인터페이스에서 사용자 정의 인터페이스를 상속받는다.
(4) 사용자 정의 메서드 호출 코드
List<Member> result = memberRepository.findMemberCustom();
Impl 대신 다른 이름으로 변경하고 싶으면?
- 두 가지 방법을 소개한다.
- Impl이 기본값이다.
(1) XML 설정
<repositories base-package="study.datajpa.repository" repository-impl-postfix="Impl" />
(2) JavaConfig 설정
@EnableJpaRepositories(basePackages = "study.datajpa.repository", repositoryImplementationPostfix = "Impl")
참고 : 실무에서는 주로 QueryDSL이나 SpringJdbcTemplate을 함께 사용할 때 사용자 정의 리포지토리 기능을 자주 사용한다.
참고 : 항상 사용자 정의 리포지토리가 필요한 것은 아니다.
그냥 임의의 리포지토리를 만들어도 된다. 예를 들어 MemberQueryRepository를 인터페이스가 아닌 클래스로 만들고 스프링 빈으로 등록해서 그냥 직접 사용해도 된다.
이 경우 스프링 데이터 JPA와는 아무런 관계없이 별도로 동작한다.
사용자 정의 리포지토리 구현 최신 방식
스프링 데이터 2.x부터는 사용자 정의 구현 클래스에 리포지토리 인터페이스 이름 + Impl을 적용하는 대신에
사용자 정의 인터페이스 명 + Impl 방식도 지원한다.
예를 들어서 위 예제의 MemberImpl 대신에 MemberRepositoryCustomImpl 같이 구현해도 된다.
@RequiredArgsConstructor
public class MemberRepositoryCustomImpl implements MemberRepositoryCustom {
private final EntityManager em;
@Override
public List<Member> findMemberCustom() {
return em.createQuery("select m from Member m").getResultList();
}
}
- 기존 방식보다 이 방식이 사용자 정의 인터페이스 이름과 구현 클래스 이름이 비슷하므로 더 직관적이다.
- 추가로 여러 인터페이스를 분리해서 구현하는 것도 가능하기 때문에 새롭게 변경된 이 방식을 사용하는 것을 더 권장한다.
반응형
'JPA > SpringDataJPA' 카테고리의 다른 글
[SpringDataJPA] Auditing (0) | 2022.06.04 |
---|---|
[SpringDataJPA] 페이징 (Paging) (0) | 2022.06.03 |
[SpringDataJPA] 쿼리 메소드 (Query Method) (0) | 2022.06.03 |
[SpringDataJPA] JpaRepository 인터페이스 (0) | 2022.06.03 |
댓글