[SpringData] 사용자 정의 리포지토리

KMS·2022년 4월 26일
0

SpringData

목록 보기
5/9

지금까지 JpaRepository<Entity, ID>를 상속받은 인터페이스를 통해 메서드를 쿼리로 변경되는 것들을 학습해봤습니다. 하지만, 단순히 메서드 이름 또는 @Query 애노테이션을 통해 모든 쿼리를 작성하기에는 어렵습니다.
쿼리가 복잡해지거나, 동적 쿼리라서 QueryDSL 등을 사용해야 되는 경우에는 어떻게 할까요? 이런 경우에는 JPA에서 배운 방식대로 메서드 안에서 구현을 하면 됩니다.
하지만, SpringData에서는 리포지토리가 인터페이스이므로, 리포지토리 안에서 구현을 할 수가 없습니다. 그러면 '클래스로 바꾸면 되지 않을까?' 라는 생각이 듭니다. 클래스로 구현할 경우, JpaRepository<Entity, ID>에 정의된 모든 메서드들도 구현을 해줘야 하기 때문에 리포지토리가 너무 복잡해 집니다.
그러면 이 문제를 어떻게 해결할지 알아보도록 하겠습니다.

사용자 정의 인터페이스 구현

MemberDataRepositoryCustom

public interface MemberDataRepositoryCustom {

    List<Member> findMemberCustom();
}

MemberDataRepositoryImpl

@RequiredArgsConstructor
public class MemberDataRepositoryImpl implements MemberDataRepositoryCustom {

    private final EntityManager em;

    @Override
    public List<Member> findMemberCustom() {
        return em.createQuery("select m from Member m", Member.class)
                .getResultList();
    }
}

MemberDataRepository

public interface MemberDataRepository extends JpaRepository<Member, Long>, MemberDataRepositoryCustom {
(생략)
}

기존에는 JpaRepository<Entity, ID>를 상속받은 MemberDataRepository에서 모든 쿼리들을 생성했습니다. 이제는 Custom이랑 디렉토리를 생성 후, 해당 디렉토리에 MemberDataRepositoryCustom라는 인터페이스와 MeberDataRepositoryImpl이라는 클래스를 생성합니다. 이때, MemberDataRepositoryCustom에 필요한 메서드를 정의하고, MemberDataRepositoryImpl에서는 MemberDataRepositoryCustom을 상속 받아서 선언한 메서드를 구현해서, 필요한 쿼리문이 실행되도록 합니다.
구현한 후, MemberDataRepository가 MemberDataRepositoryCustom을 상속 받으면, MemberDataRepository에서 MemberDataRepositoryImpl에서 구현한 메서드들도 실행이 가능해집니다.

여기서 주목할 점은, MemberDataRepository에서 MemberDataRepositoryCustom를 상속 받았는데, MemberDataRepositoryImpl에서 구현한 메서드가 실행된다는 점입니다. 그렇게 되는 이유는, MemberDataRepositoryImpl 클래스의 이름을 관례에 따라서 (JpaRepository를 상속받은 인터페이스의 이름 + Impl) Or (사용자 정의 인터페이스 명 + Impl) 으로 설정하면 자동으로 스프링 데이터 JPA가 자동으로 스프링 빈 등록을 해주기 때문입니다.
그러므로, 클래스 이름을 MemberDataRepositoryImpl 또는 MemberDataRepositoryCustomImpl 으로 설정하면 자동으로 스프링 빈 등록이 됩니다.

이게 최선의 방법일까?

사실 이것이 최선의 방법이라고 할 수는 없습니다. SpringData로 개발을 하다보면 복잡한 쿼리 또는 동적 쿼리가 필요한 경우가 생기기 때문에 사용자 정의 리포지토리가 필요합니다. 다만, 이번 포스팅에서의 방식으로 모든 리포지토리를 구현하고 상속 받도록하면, 하나의 리포지토리에 너무 많은 리포지토리들이 추가되고, 유지보수에 어려움이 생깁니다. 그렇기 때문에, 핵심 비즈니스 로직인 경우면 이러한 방식으로 사용자 정의 리포지토리를 생성해서 상속 받도록 하고, 그 외 로직들은 순수 JPA 방식으로 개발해서 따로 관리하는 것이 권장됩니다.

profile
Student at Sejong University Department of Software

0개의 댓글