[Spring Data JPA] 공통 인터페이스
공통 인터페이스 기능
예제 도메인 모델
순수 JPA 기반 Repository
- 기본 CRUD
- 저장
- 변경 -> 변경 감지
- 삭제
- 전체 조회
- 단건 조회
- 카운트
MemberJpaRepository
@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();
}
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
는 회원 Repository와 거의 동일하기 때문에 생략..
공통 인터페이스 설정
JavaConfig 설정 - 스프링 부트 사용시 생략 가능
@Configuration
@EnableJpaRepositories(basePackages = "jpabook.jpashop.repository")
public class AppConfig {}
- 스프링 부트 사용시
@SpringBootApplication
위치를 지정(해당 패키지와 하위 패키지 인식) - 만약 위치가 달라지면
@EnableJpaRepositories
필요
공통 인터페이스 적용
순수 JPA로 구현한 MemberJpaRepository
대신에 스프링 데이터 JPA가 제공하는 공통 인터페이스 사용
스프링 데이터 JPA 기반 MemberRepository
public interface MemberRepository extends JpaRepository<Member, Long> {}
- 기존 순수 JPA 기반 테스트에서 사용했던 코드를 그대로 적용해보면 동일한 방식으로 동작한다.
- Generic
- T : 엔티티 타입
- ID : 식별자 타입(PK)
TeamRepository
는 동일하기 때문에 생략..
스프링 데이터 JPA가 구현 클래스 대신 생성
org.springframework.data.repository.Repository
를 구현한 클래스는 스캔 대상- MemberRepository 인터페이스가 동작한 이유
@Repository
애노테이션 생략 가능- 컴포넌트 스캔을 스프링 데이터 JPA가 자동으로 처리
- JPA 예외를 스프링 예외로 변환하는 과정도 자동으로 처리
공통 인터페이스 분석
- JpaRepository 인터페이스 : 공통 CRUD 제공
- 제네릭은 <엔티티 타입, 식별자 타입> 설정
JpaRepository
공통 기능 인터페이스
public interface JpaRepository<T, ID extends Serializable>
extends PagingAndSortingRepository<T, ID>
{
...
}
JpaRepository
를 사용하는 인터페이스
public interface MemberRepository extends JpaRepository<Member, Long> {}
공통 인터페이스 구성
제네릭 타입
T
: 엔티티ID
: 엔티티의 식별자 타입(PK)S
: 엔티티와 그 자식 타입
주요 메서드
save(S)
: 새로운 엔티티는 저장하고, 이미 있는 엔티티는 병합한다.delete(T)
: 엔티티 하나를 삭제한다. 내부에서EntityManager.remove()
호출findById(ID)
: 엔티티 하나를 조회한다. 내부에서EntityManager.find()
호출getOne(Id)
: 엔티티를 프록시로 조회한다. 내부에서EntityManager.getReference()
호출findAll(...)
: 모든 엔티티를 조회한다. 정렬(Sort
)이나 페이징(Pageable
) 조건을 파라미터로 제공할 수 있다.
[참고]
JpaRepository
는 대부분의 공통 메서드를 제공한다.
<출처 : 인프런 - 실전! 스프링 데이터 JPA(김영한)>
댓글남기기