Springboot

스프링부트 Repository 커스텀 (분리)

땍땍 2024. 9. 23. 16:09

프로젝트의 규모가 크지 않거나, 시작 단계일 경우 하나의 Repository에서 모든 쿼리를 관리하는 경우를 종종 볼 수 있을 것이다.

public interface MemberRepository extends JpaRepository<Members, Long> {

    Optional<Members> findByEmailAndNickname(String email, String nickname);
    List<Members> findByRole(Role role);

		... 등등
}

위의 코드는 아직 정의된 메소드가 두 가지 밖에 없기에 잘 와닿지 않겠지만, 관련 쿼리가 몇 십,백개가 넘어가거나

현재는 Jpa만 사용하지만 jpsql 혹은 querydsl 등으로 직접 쿼리문을 작성하는 경우 하나에 파일에서 관리하게 되면 코드가 복잡해져 유지보수에 있어 어려움을 느낄 수 있을 것이다.

이러한 사항은 Repository를 분리하여 사용함으로 해결할 수 있다.

아래는 Repository를 분리하여 jpa에서 지원하지 않는 limit 을 직접 구현해보는 예시이다.

( 물론 jpa에서도 page 등의 방법으로 비슷하게 구현할 수 있는 방법은 존재한다. )

public interface MemberRepository extends JpaRepository<Members, Long>, MemberRepositoryCustom {
    Optional<Members> findByEmailAndNickname(String email, String nickname);
}
public interface MemberRepositoryCustom {
  public List<Members> findMembersLimit(int limit);
}
@RequiredArgsConstructor
public class MemberRepositoryImpl implements MemberRepositoryCustom {

  private final EntityManager em;

  @Override
  public List<Members> findMembersLimit(int limit) {
    String jpql = "select m from Members m";
    TypedQuery<Members> query = em.createQuery(jpql, Members.class);
    query.setMaxResults(limit);
    return query.getResultList();
  }
}

위와 같이 MemberRepository는 JpaRepository와 MemberRepsoitoryCustom를 상속 받아 Service 단에서는 MemberRepository만을 호출해도 기본적인 Jpa의 CRUD와 직접 작성한 쿼리를 모두 사용할 수 있으며,

Jpa이외의 직접 구현하는 쿼리는 MemberRepsoitoryCustom과 MemberRepositoryImpl에서 작성 및 관리하여 유지보수를 용이하게 할 수 있다.