[SpringBoot] 스프링 데이터 JPA - 공통 인터페이스 기능

sorzzzzy·2022년 2월 14일
0

Spring Boot

목록 보기
2/3
post-thumbnail

스프링 데이터 JPA가 제공하는 공통 인터페이스 기능에 대하여 알아보자.

  • 순수 JPA 기반 리포지토리 만들기
  • 스프링 데이터 JPA 공통 인터페이스 소개
  • 스프링 데이터 JPA 공통 인터페이스 활용

위 순서대로 진행하겠다.


🏷 순수 JPA 기반 리포지토리 만들기


비교를 하기 위해 먼저 지난 시간에 만들어뒀던 순수 JPA 기반 리포지토리를 수정하겠다.

✔️ MemberJpaRepository.java 클래스

@Repository
public class MemberJpaRepository {
    // Jpa를 사용하기 위해서는 EntityManager가 필요함
    // @PersistenceContext를 사용하면 엔티티 매니저를 가져다줌
    @PersistenceContext
    private EntityManager em;

    public Member save(Member member) {
        // 멤버 저장 후 반환
        em.persist(member);
        return member;
    }

    public void delete(Member member) {
        em.remove(member);
    }

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

    public Optional<Member> findById(Long id) {
        Member member = em.find(Member.class, id);
        return Optional.ofNullable(member);
    }

    public long count() {
        return em.createQuery("select count(m) from Member m", Long.class)
                .getSingleResult();
    }

    public Member find(Long id) {
        return em.find(Member.class, id);
    }

}

삭제 / 전체 조회 / 단건 조회 / 카운트 기능을 추가하였다.


이제 팀 리포지토리를 만들어보자.

✔️ TeamJpaRepository.java 클래스

@Repository
public class TeamJpaRepository {

    @PersistenceContext
    EntityManager em;

    public Team save(Team team) {
        em.persist(team);
        return team;
    }

    public void delete(Team team) {
        em.remove(team);
    }

    public List<Team> findAll() {
        return em.createQuery("select t from Team t", Team.class)
                .getResultList();
    }

    public Optional<Team> findById(Long id) {
        Team team = em.find(Team.class, id);
        return Optional.ofNullable(team);
    }

    public long count() {
        return em.createQuery("select count(t) from Team t", Long.class)
                .getSingleResult();
    }
}

모든 기능이 회원 리포지토리와 매우 비슷하다.


✔️ MemberJpaRepositoryTest.java

@Test
    public void basicCRUD() {

        // 멤버 생성
        Member member1 = new Member("member1");
        Member member2 = new Member("member2");
        memberJpaRepository.save(member1);
        memberJpaRepository.save(member2);

        // 단건 조회 검증
        Member findMember1 = memberJpaRepository.findById(member1.getId()).get();
        Member findMember2 = memberJpaRepository.findById(member2.getId()).get();
        assertThat(findMember1).isEqualTo(member1);
        assertThat(findMember2).isEqualTo(member2);

        // 리스트 조회 검증
        List<Member> all = memberJpaRepository.findAll();
        assertThat(all.size()).isEqualTo(2);

        // 카운트 검증
        long count = memberJpaRepository.count();
        assertThat(count).isEqualTo(2);

        // 회원 삭제 검증
        memberJpaRepository.delete(member1);
        memberJpaRepository.delete(member2);
        long deleteCount = memberJpaRepository.count();
        assertThat(deleteCount).isEqualTo(0);
    }

지난 시간에 만들어뒀던 순수 JPA 기반 리포지토리 테스트에 CRUD 기능을 테스트하는 코드를 추가하였다.

잘 동작한다.


🏷 스프링 데이터 JPA 공통 인터페이스 소개


이제 순수 JPA로 구현한 MemberJpaRepository 대신, 지난 시간에 생성했던 스프링 데이터 JPA가 제공하는 공통 인터페이스 MemberRepository 를 사용해서 테스트 해보겠다.


✔️ MemberRepositoryTest

@Test
    public void basicCRUD() {

        // 멤버 생성
        Member member1 = new Member("member1");
        Member member2 = new Member("member2");
        memberRepository.save(member1);
        memberRepository.save(member2);

        // 단건 조회 검증
        Member findMember1 = memberRepository.findById(member1.getId()).get();
        Member findMember2 = memberRepository.findById(member2.getId()).get();
        assertThat(findMember1).isEqualTo(member1);
        assertThat(findMember2).isEqualTo(member2);

        // 리스트 조회 검증
        List<Member> all = memberRepository.findAll();
        assertThat(all.size()).isEqualTo(2);

        // 카운트 검증
        long count = memberRepository.count();
        assertThat(count).isEqualTo(2);

        // 회원 삭제 검증
        memberRepository.delete(member1);
        memberRepository.delete(member2);
        long deleteCount = memberRepository.count();
        assertThat(deleteCount).isEqualTo(0);
    }

순수 JPA 기반 리포지토리 테스트와 매우 비슷하지만 이번에는 스프링 데이터 JPA가 제공하는 인터페이스를 사용하고 있다.

결과는 역시나 성공이다.
어떻게 이런 결과가 나오는지 이제부터 자세히 살펴보자.


🏷 스프링 데이터 JPA 공통 인터페이스 활용


MemberRepository 인터페이스가 상속받고 있는 JpaRepository 인터페이스를 살펴보자.

JpaReopository 인터페이스는 PagingAndSortingRepository 인터페이스를 상속받고 있고,
PagingAndSortingRepository 인터페이스는 CrudReopository 인터페이스를,
CrudReopository 인터페이스는 Repository 인터페이스를 상속받고 있다.
➡️ 최상위 Repository 인터페이스

스프링 데이터는 공통 부분을 제공하고, 스프링 데이터 JPAJPA에 특화된 기능을 제공한다.

JpaRepository 는 개발자들이 생각할 수 있는 대부분의 공통 메서드를 제공한다고 보면 된다.

📌 최근에 T findOne(ID) ➡️ Optional<T> findById(ID) 로 변경되었다.


주요 메소드를 간단히 살펴보자.

  • save(S)
    새로운 엔티티는 저장하고 이미 있는 엔티티는 병합한다. (merge 기능 함께 제공)
  • delete(T)
    엔티티 하나를 삭제한다.
    내부에서 EntityManager.remove() 메소드를 호출한다.
  • findById(ID)
    엔티티 하나를 조회한다.
    내부에서 EntityManager.find() 메소드를 호출한다.
  • getOne(ID)
    엔티티를 프록시로 조회한다.
    내부에서 EntityManager.getReference() 메소드를 호출한다.
  • findAll(...)
    모든 엔티티를 조회한다.
    정렬(Sort)이나 페이징(Pageable) 조건을 파라미터로 제공할 수 있다.
profile
Backend Developer

0개의 댓글