Spring/SpringDataJPA

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

느리지만 꾸준하게 2022. 4. 18. 00:43

스프링 데이터 JPA 리포지토리는 인터페이스가 구현만 되어있고 모두 상속을 받아야 하기 때문에 현실적이지 않다.

 

스프링 데이터 JPA가 아니라 JDBC를 직접 활용을 해서 기능을 쓴다거나 MyBatis library 기능을 쓴다거나 완전히 다른 Repository 기능을 쓰고 싶을 때 이런걸 쓸 수 있게 열어놓은 것이 사용자 정의 리포지토리 구현이다.

 

 

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

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

 

 

그리고 여러 커스텀 기능을 스프링 데이터 JPA가 제공해주는 것을 알고 코드를 작성해보자.

 

// MemberRepositoryCustom

package study.datajpa.repository;

import study.datajpa.entity.Member;

import java.util.List;

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

@RequiredArgsConstructor
public class MemberRepositoryImpl implements MemberRepositoryCustom{

    private final EntityManager em;


    // @RequiredArgsConstructor 인해 생략가능
//    public MemberRepositoryImpl(EntityManager em) {
//        this.em = em;
//    }

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

 

 

 

MemberRepository Interface 에다가 아래와 같이 설정을 해주자.

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

 

아래처럼 해서 test를 돌리면

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

 

Member를 그대로 찍어온다.

select
        member0_.member_id as member_i1_0_,
        member0_.age as age2_0_,
        member0_.tema_id as tema_id4_0_,
        member0_.username as username3_0_ 
    from
        member member0_

 

여기에서 구현된것이

// MemberRepositoryCustom Interface

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

정확하게 실행이 된 것을 확인할 수 있다.

// MemberRepositoryImpl Class

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

 

 

규칙이 있는데 

MemberRepositoryImpl에서 아래 MemberRepositoryImpl 명칭을 맞춰줘야 한다.

// MemberRepositoryCustom

@RequiredArgsConstructor
public class MemberRepositoryImpl implements MemberRepositoryCustom{

즉 MemberRepository Interface에서 MemberRepository 뒤에 Impl붙여 MemberRepositoryImpl 규칙을 맞춰줘야 한다. 

// MemberRepository Interface

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

 

 

그러면 이제 findMemberCustom 구현체로 

// MemberRepositoryTest

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

 

MemberRepositoryCustom Interface를 상속한 

package study.datajpa.repository;

import study.datajpa.entity.Member;

import java.util.List;

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

 

 

MemberRepositoryImpl을 찾아서 호출해준다.

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

 

 

참고사항을 보면 아래와 같다.

  • 실무에서 주로 QueryDSL 이나 SpringJdbcTemplate을 함께 사용할 때 사용자 정의 리포지토리 기능 자주 사용가능하다.
  • 항상 사용자 정의 리포지토리가 필요한 것은 아니고 임의의 리포지토리를 생성해도 괜찮다.
  • 아래의 코드 예시를 보자.

 

Interface가 아닌 Class로 MemberQueryRepository를 만들고 스프링 빈으로 등록해서 직접 사용해도 된다.

이럴 경우 스프링 데이터 JPA와는 관계없이 별도로 동작한다.

package study.datajpa.repository;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import study.datajpa.entity.Member;

import javax.persistence.EntityManager;
import java.util.List;

@Repository
@RequiredArgsConstructor
public class MemberQueryRepository {

    private final EntityManager em;

    List<Member> findAllMembers() {
        return em.createQuery("select m from Member m")
                .getResultList();
    }
}

 

사용하는 클라이언트 코드를 MemberRepositoryTest라고 하면 아래와 같이 Autowired를 MemberQueryRepository에다가 설정을 해준다.

@Rollback(false)
class MemberRepositoryTest {

    @Autowired MemberRepository memberRepository;
    @Autowired TeamRepository teamRepository;
    @PersistenceContext
    EntityManager em;

    @Autowired
    MemberQueryRepository memberQueryRepository;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<출처 김영한: 실전! 스프링 데이터 JPA >

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%8D%B0%EC%9D%B4%ED%84%B0-JPA-%EC%8B%A4%EC%A0%84/dashboard

 

실전! 스프링 데이터 JPA - 인프런 | 강의

스프링 데이터 JPA는 기존의 한계를 넘어 마치 마법처럼 리포지토리에 구현 클래스 없이 인터페이스만으로 개발을 완료할 수 있습니다. 그리고 반복 개발해온 기본 CRUD 기능도 모두 제공합니다.

www.inflearn.com

 

 

 

 

 

 

'Spring > SpringDataJPA' 카테고리의 다른 글

스프링 데이터 JPA 구현체 분석  (0) 2022.04.18
Web 확장 - 도메인 클래스 컨버터 & 페이징과 정렬  (0) 2022.04.18
JPA Hint & Lock  (0) 2022.04.17
@EntityGraph  (0) 2022.04.17
벌크성 수정 쿼리(error 해결중)  (0) 2022.04.17