본문 바로가기
개발/JPA

[JPA] 스프링 데이터 - 공통 인터페이스 기능

by devhooney 2022. 7. 25.
728x90

김영한님의 실전! 스프링 데이터 JPA 정리

1. 공통 인터페이스 설정

- JavaConfig 설정 - 스프링 부트 사용 시 생략 가능

@Configuration
@EnableJpaRepositories(basePackages = "jpabook.jpashop.repository")
public class AppConfig {}

- 스프링 부트 사용 시 @SpringBootApplication 위치를 지정(해당 패키지와 하위 패키지 인식)

- 만약 위치가 달라지면 @EnableJpaRepositories 필요

- 스프링 데이터 JPA가 구현 클래스 대신 생성

- org.springframework.data.repository.Repository를 구현한 클래스는 스캔 대상

-> memberRepository.getClass() 결과 class com.sun.proxy.$ProxyXXX

- @Repository 어노테이션 생략 가능

(1) 컴포넌트 스캔을 스프링 데이터 JPA가 자동으로 처리

(2) JPA 예외를 스프링 예외로 변환하는 과정도 자동으로 처리

 

2. 공통 인터페이스 적용

- 순수 JPA로 구현한 MemberJpaRepository 대신에 스프링 데이터가 JPA가 제공하는 공통 인터페이스 사용

- 스프링 데이터 JPA 기반 MemberRepository

// JpaRepository 인터페이스: 공통 CRUD 제공
// 제네릭은 <엔티티 타입, 식별자 타입> 설정
public interface MemberRepository extends JpaRepository<Member,Long> {}

 

3. 공통 인터페이스 구성

- spring-data-commons라는 공통의 프로젝트가 있고 그 밑에 jpa, mongoDB, redis 등의 각각에 특화된 기능들이 있는 라이브러리가 있다.

 

4. 공통 인터페이스 주의사항

- 추가적 쿼리를 만들 경우 @Transactional(readOnly = true)를 걸어주고 데이터 변경이 필요한 경우 @Transactional을 붙여준다.

대부분 repository의 쿼리의 경우 조회쿼리가 대부분이므로 전체에 readOnly를 걸어주고 변경하는 부분에만 따로 Transactional을 붙여준다.

- 기본적으로 JpaRepository는 조회용에는 @Transactional(readOnly = true), save같은 데이터변경에는 @Transactional이 붙어있다.

readOnly가 붙은 조회용 쿼리를 사용하면 스냅샷이 생기지 않는다. 즉, 영속성 컨텍스트에서 관리는 하고 있지만 dirty checking을 안하기 때문에 수정해도 DB에 결과가 반영되지 않는다. 이때는 반드시 @Transactional 애노테이션이 붙은 곳에서 데이터를 수정해야 한다.

- T findOne(ID) -> Optional findById(ID) 변경

- 제네릭 타입

- T: 엔티티

- ID: 엔티티의 식별자 타입

- S: 엔티티와 그 자식 타입

- 주요 메소드

(1) save(S): 새로운 엔티티는 저장하고 이미 있는 엔티티는 병합한다.

(2) delete(T): 엔티티 하나를 삭제한다. 내부에서 EntityManager.remove() 호출

(3) findById(ID): 엔티티 하나를 조회한다. 내부에서 EntityManager.find() 호출

(4) getOne(ID): 엔티티를 프록시로 조회한다. 내부에서 EntityManager.getReference() 호출

(5) findAll(...): 모든 엔티티를 조회한다. 정렬이나 페이징 조건을 파라미터로 제공할 수 있다.

 

참고: JpaRepository는 대부분의 공통 메소드를 제공한다.

728x90