본문 바로가기

JPA

[Spring Data JPA] 사용자 정의 리포지토리 구현

사용자 정의 리포지토리 구현

스프링 데이터 JPA 리포지토리는 인터페이스만 정의하고 구현체는 스프링이 자동 생성을 한다.

스프링 데이터 JPA가 제공하는 인터페이스를 직접 구현하면 상속을 받아야 하니 구현해야 하는 기능이 너무 많다.

다양한 이유로 인터페이스의 메서드를 직접 구현하고 싶다면?

  • JPA 직접 사용('EntityManager')
  • 스프링 JDBC Template 사용
  • MyBatis 사용
  • 데이터베이스 커넥션 직접 사용 등등...
  • Querydsl 사용

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", Member.class)
                .getResultList();
    }
}

/**
* 기존 방식보다 이 방식이 사용자 정의 인터페이스 이름과 구현 클래스 이름이 비슷하므로 더 직관적이다. 
* 추가로 여러 인터페이스를 분리해서 구현하는 것도 가능하기 때문에 새롭게 변경된 이 방식을 사용하는 것을 더 권장한다.
*/
@RequiredArgsConstructor
 public class MemberRepositoryCustomImpl implements MemberRepositoryCustom {
 
     private final EntityManager em;
     
     @Override
     public List<Member> findMemberCustom() {
         return em.createQuery("select m from Member m")
                 .getResultList();
    } 
}
  • 규칙: 리포지토리 인터페이스 이름 + `Impl`
  • 스프링 데이터 JPA가 인식해서 스프링 빈으로 등록
  • 스프링 데이터 2.x 부터는 사용자 정의 구현 클래스에 리포지토리 인터페이스 이름 + `Impl` 을 적용하는 대신에 사용자 정의 인터페이스 명 + `Impl` 방식도 지원한다.
  • 예를 들어서 위 예제의 `MemberRepositoryImpl` 대신에 `MemberRepositoryCustomImpl` 같이 구현해도 된.

3. 사용자 정의 인터페이스 상속

public interface MemberRepository
          extends JpaRepository<Member, Long>, MemberRepositoryCustom {
}

 

사용자 정의 메서드 호출 코드

@Test
public void callCustom() {
    List<Member> result = memberRepository.findMemberCustom();
}

 

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와는 아무런 관계 없이 별도로 동작한다.