스프링 데이터 JPA - 공통 인터페이스 설정 및 적용
오늘은 JpaRepository 에 대해서 알아보자. JavaConfig 설정 - 스프링 부트 사용 시 생략 가능
1
2
3
4
5
6
@Configuration
@EnableJpaRepositories(basePackages =
"jpabook.jpashop.reopsitory")
public class Appconfig {
...
}
MemberReopository.java
1
2
3
4
5
6
7
package study.datajpa.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import study.datajpa.entity.Member;
public interface MemberRepository extends JpaRepository<Member, Long> {
}
이 코드는 인터페이스고 안에 지정된 메서드도 없다. 그저 JpaRepository 인터페이스만 상속 받고 있다.
그런데 어떻게 작동을 할까.테스트 코드에서 한번 찍어보자
1
2
3
4
5
6
7
8
9
10
11
12
13
@SpringBootTest
@Transactional
@Rollback(value = false)
class MemberRepositoryTest {
@Autowired MemberRepository memberRepository;
@Test
@DisplayName("")
void testMember() throws Exception {
//given
System.out.println("memberRepository = " + memberRepository.getClass());
}

무슨 프록시 객체가 찍혀있다. 스프링이 Autowired 하면서 구현체를 인젝션 해버린거다.

JpaRepository를 가보면 엄청나게 많은 메서드들이 정의되어 있다.
그래서
1
2
3
4
5
6
7
package study.datajpa.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import study.datajpa.entity.Member;
public interface MemberRepository extends JpaRepository<Member, Long> {
}
이렇게만 작성하면, @Repository, @PersistenceContext 이런 어노테이션이 필요 없고 그냥 사용만 하면된다.
extends JpaRepository<엔티티, 엔티티에 매핑된 PK의 타입> 이렇게 사용한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@Autowired MemberRepository memberRepository;
@Test
@DisplayName("CRUD test")
void basicCRUD() throws Exception {
//given
Member member1 = new Member("member1");
Member member2 = new Member("member2");
memberRepository.save(member1);
memberRepository.save(member2);
//when
Member findMember1 = memberRepository.findById(member1.getId()).get();
Member findMember2 = memberRepository.findById(member2.getId()).get();
//then
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에 관련된 건 jpa 패키지 내에 있고 공통적인 페이징이나 crud 이런 건 그냥 스프링 데이터 패키지 내에 있다. 이를 통해 뭐 NoSQL 이라던가 jpa를 사용하지 않는 환경에서 페이징 과 같은 기능을 사용할 수도 있을꺼라 생각된다.
주의
T findOne(ID)->Optional<T> findById(ID)로 변경, 옵셔널을 꼭 써야한다.
제네릭 타입
T: 엔티티ID: 엔티티의 식별자 타입S: 엔티티와 그 자식 타입
주요 메서드
save(S): 새로운 엔티티는 저장하고, 이미 있는 엔티티는 병합(수정)한다.delete(T): 엔티티 하나를 삭제한다. 내부에서EntityManager.remove()호출findById(ID): 엔티티 하나를 조회한다.EntityManager.find()호출getOne(ID): 엔티티를 프록시로 조회한다. 내부에서EntityManager.getReference()호출findAll(...): 모든 엔티티를 조회한다. 정렬(Sort)이나 페이징(Pageable) 조건을 파라미터로 제공할 수 있다.
참고 :
JpaRepository는 대부분의 공통 메서드를 제공한다.
댓글남기기