
JpaRepository interface를 상속받는 새로운 MemberRepository interface를 생성한다.
extends JpaRepository<엔티티, pk타입>
public interface MemberRepository extends JpaRepository<Member, Long> {
}
memberRepository class 출력해보니 proxy 객체임을 확인
@SpringBootTest
@Transactional
@Rollback(value = false)
class MemberRepositoryTest {
@Autowired MemberRepository memberRepository;
@Test
public void testMember(){
System.out.println("memberRepository = " + memberRepository.getClass());
// class com.sun.proxy.$Proxy121 (스프링 데이터 JPA가 MemberRepository 인터페이스 보고 프록시 객체(구현체)를 만들어서 주입)
}
spring data jpa가인터페이스 구현체를 만들어서,injection해줍니다!

MemberRepository에@Repository어노테이션 생략이 가능하다
컴포넌트 스캔을 Spring Data JPA가 자동으로 처리
MemberJpaRepositoryTest의 basicCRUD에서
순수 JPA를 사용한 레포지토리인MemberJpaRepository를Spring Data JPA를 사용한MemberRepository로 변경
😄 그 결과 정상적으로 동작함!
@SpringBootTest
@Transactional
@Rollback(value = false)
class MemberRepositoryTest {
@Autowired MemberRepository memberRepository;
@PersistenceContext EntityManager em;
@Test
public void basicCRUD(){// MemberJpaRepository -> MemberRepository로 변경
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 deletedCount = memberRepository.count();
assertThat(deletedCount).isEqualTo(0);
}
}
JPA에 특화된 기능을 가진 Interface
package org.springframework.data.jpa.repository;
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
...
}
Spring Data Project라는 공통 프로젝트가 있고, 하위에 Spring Data Jpa, Spring Data Mongo, Spring Data Redis등등이 있다.
org.springframework.data : 공통의 CRUD
org.springframework.data.jpa : JPA 특화 기능
페이징과 정렬에 관련된 기능을 가진 Interface
package org.springframework.data.repository;
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
}
package : org.springframework.data
=> 페이징과 정렬은 관계형 DB, NoSQL, MongoDB... 다 비슷
=> 그래서 모든 DB에 공통적으로 적용되는 공통 인터페이스 제공
기본적인 CRUD 기능을 가진 interface
package org.springframework.data.repository;
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
<S extends T> S save(S entity);
Optional<T> findById(ID id);
Iterable<T> findAll();
// ... 이외에도 많은 기본적인 CRUD 함수
}

T : 엔티티
ID : 엔티티의 PK
S : 엔티티와 그 자식 타입
save(S) 새로운 엔티티 저장, 이미 있는 엔티티는 병합
delete(T) 엔티티 하나 삭제 (내부에서 em.remove() 호출)
findById(ID) 엔티티 하나 조회 (내부에서 em.find() 호출)
getOne(ID) 엔티티를 프록시로 조회 (내부에서 em.getReference() 호출)
findAll(...) 모든 엔티티 조회. 정렬(Sort)나 페이징(Pageable) 조건을 파라미터로 제공할 수 있다.
😄 JpaRepository는 상상할 수 있는 공통 기능을 대부분 제공한다고 생각하면 된다!!
Spring Data JPA는 스프링 프레임워크에서 JPA를 편리하게 사용할 수 있도록 지원하는 프로젝트
CRUD를 처리하기 위한 JpaRepository라는 공통 Interface 제공
리포지토리 개발할 때 인터페이스만 작성하면, 실행시점에 Spring Data JPA가 구현 객체를 동적으로 생성해서 주입
=> 데이터 접근 계층(repository) 개발할 때, 구현 클래스 없이 interface만 작성해도 개발 완료!
김영한, ⌜자바 ORM 표준 JPA 프로그래밍⌟