BackEnd/스프링 데이터 JPA

공통 인터페이스 기능

인프라 감자 2023. 1. 12. 13:45

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

저번 강의에서 했던 방식으로 JPA만을 가지고 리포지토리를 만든다.

 

구현할 요소

  • 저장
  • 변경 -> 변경감지 사용
  • 삭제
  • 전체 조회
  • 단건 조회
  • 카운트

 

순수 JPA 기반 리포지토리 - 회원

@Repository
public class MemberJpaRepository {

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

    /**
     * id 로 조회
     */
    public Optional<Member> findById(Long Id){
        Member member = em.find(Member.class, Id);
        return Optional.ofNullable(member);
    }

    /**
     * count
     */
    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);
    }
}

teamRepository는 여기서 Team으로만 바꾸면 된다.

 

공통 인터페이스 설정

package study.datajpa.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import study.datajpa.entity.Member;

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

interface만 만들어 놓으면 Spring Data Jpa가 모두 구현해 논다.

  • memberRepository.getClass() class com.sun.proxy.$ProxyXXX 직접 출력을 해보면 프록시가 나온다. 
  • 스프링 데이터 JPA가 프록시로 가짜 클레스를 만든 다음에 주입을 해준 것이다.
  • @Repository 애노테이션 생략 가능하다.

 

공통 인터페이스 적용

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class MemberRepositoryTest {

    @Autowired MemberRepository memberRepository;


    @Test
    public void testMember() throws Exception{
         
        Member member = new Member("memberA");
        Member savedMember = memberRepository.save(member);

        Member findMember = memberRepository.findById(savedMember.getId()).get();
        Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());

        Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
        Assertions.assertThat(findMember).isEqualTo(member);
    }
}

구현체가 없고 인터페이스만 있지만 정상적으로 작동한다. 

 

 

공통 인터페이스 분석

JpaRepository 인터페이스는 공통 CRUD를 제공한다. 

제네릭은 <엔티티 타입, 식별자 타입> 설정이다.

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

위의 코드 처럼 구현하면 모든 CRUD를 사용가능하다.

제네릭 타입

  • T : 엔티티
  • ID : 엔티티의 식별자 타입
  • S : 엔티티와 그 자식 타입

 

주요 메서드

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

 

출처

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