순수 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 ) 조건을 파라미터로 제공할 수 있다
출처
실전! 스프링 데이터 JPA - 인프런 | 강의
스프링 데이터 JPA는 기존의 한계를 넘어 마치 마법처럼 리포지토리에 구현 클래스 없이 인터페이스만으로 개발을 완료할 수 있습니다. 그리고 반복 개발해온 기본 CRUD 기능도 모두 제공합니다.
www.inflearn.com
'BackEnd > 스프링 데이터 JPA' 카테고리의 다른 글
확장 기능 (0) | 2023.01.23 |
---|---|
@EntityGraph, JPA Hint @ Lock (0) | 2023.01.21 |
벌크성 수정 쿼리 (1) | 2023.01.20 |
JPA 페이징 처리 (0) | 2023.01.14 |
쿼리 메소드 기능 (0) | 2023.01.14 |