ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • #Spring Data JPA - 10 확장 기능-사용자 정의 리포지토리 구현
    카테고리 없음 2021. 3. 25. 10:00

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

     

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

    · 스프링 데이터 JPA가 제공하는 인터페이스를 직접 구현하면 구현해야 하는 기능이 너무 많음

    · 다양한 이유로 인터페이스의 메서드를 직접 구현하고 싶다면?(실무에서 굉장히 많이 사용)

        · JPA 직접 사용( EntityManager )

        · 스프링 JDBC Template 사용

        · MyBatis 사용

        · 데이터베이스 커넥션 직접 사용 등등...

        · Querydsl 사용

     

    만드는 순서

    1. 사용자 정의 인터페이스

    public interface MemberRepositoryCustom {
       List<Member> findMemberCustom();
    }

    SPRING DATA JPA가 아니라 직접 구현한 기능을 쓰고싶은 경우.
    구현은 다른 클래스에서했지만 MemberRepository에서 동작을 시키면 SPRING DATA JPA가 다른 곳에 구현되있는것을 호출하게 한다.


    - 강사님은 QueryDSL을 쓸대 커스텀해서 많이 사용.
    Tip : 간단한건 SPRING DATA JPA를쓰고 복잡한것은 QueryDSL을 쓰자

    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();
       }
       
    }

    여기서 class Naming규칙이있는데 MmeberRepository + Impl이규칙만 맞추면
    findMmeberCustom을 호출했을때 findMmeberCustom을 만든 구현체를 찾아서 호출해준다.

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

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

     

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

    List<Member> result = memberRepository.findMemberCustom();

     

    사용자 정의 구현 클래스

    · 규칙: 리포지토리 인터페이스 이름 + Impl

    · 스프링 데이터 JPA가 인식해서 스프링 빈으로 등록

     

    Impl 대신 다른 이름으로 변경하고 싶으면?

     

    XML 설정

    <repositories base-package="study.datajpa.repository"
     repository-impl-postfix="Impl" />

    JavaConfig 설정

    @EnableJpaRepositories(
        basePackages = "study.datajpa.repository",
         repositoryImplementationPostfix = "Impl"
     )
    

    참고: 실무에서는 주로 QueryDSL이나 SpringJdbcTemplate을 함께 사용할 때 사용자 정의 리포지토리 기능 자주 사용

    findByName or @Query로 해결이 되면 그냥 쓰면되지만 복잡한 동적쿼리를 구현해야할때 사용하자!!!

     

    참고: 항상 사용자 정의 리포지토리가 필요한 것은 아니다.(핵심비지니스 로직이랑 단순하게 화면에 맞춘 쿼리랑 분리하는 게 필요하다.) 그냥 임의의 리포지토리를 만들어도 된다.

    예를들어 MemberQueryRepository를 인터페이스가 아닌 클래스로 만들고 스프링 빈으로 등록해서

    그냥 직접 사용해도 된다. 물론 이 경우 스프링 데이터 JPA와는 아무런 관계 없이 별도로 동작한다.

    왠만하면 유지보수를 위해 관례를 따르고 xml과 javaConfig설정방법은 피하자

     

    사용자 정의 리포지토리 구현 최신 방식

    (참고: 강의 영상에는 없는 내용입니다.)

     

     

    스프링 데이터 2.x 부터는 사용자 정의 구현 클래스에 리포지토리 인터페이스 이름 + Impl 을 적용하는 대신에

    사용자 정의 인터페이스 명 + Impl 방식도 지원한다.

    예를 들어서 위 예제의 MemberRepositoryImpl 대신에 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();
       }
    }

    기존 방식보다 이 방식이 사용자 정의 인터페이스 이름과 구현 클래스 이름이 비슷하므로 더 직관적이다. 추가로 여러 인터페이스를 분리해서 구현하는 것도 가능하기 때문에 새롭게 변경된 이 방식을 사용하는 것을 더 권장한다.

     

     

    댓글

Designed by Tistory.