Application 과 JDBC 사이에서 동작한다.
Interface 의 모음
JPA 를 정의한 javax.persistence 패키지 대부분이 Interface 와 enum으로 구성
→ JPA 의 핵심인 EntityManager 도 interface 로 정의
→ JPA 에서 제공하는 EntityManager 로 DB 에 접근 가능
ORM 기술 표준
참고: JPA (Java Persistence API)
public interface EntityManager {
public void persist(Object entity);
public <T> T merge(T entity);
public void remove(Object entity);
public void flush();
// more...
}
@Repository // JpaRepository 를 상속하지 않고, @Repository 만 추가했음
@RequiredArgsConstructor
public class OrderRepository {
private final EntityManager em;
public void save(Order order){
em.persist(order);
}
public Order findOne(Long id){
return em.find(Order.class, id);
}
public List<Order> findAll() {
return em.createQuery("select o from Order o", Order.class)
.getResultList();
}
public List<Order> findAllWithItem() {
return em.createQuery(
"select distinct o from Order o" +
" join fetch o.member m" +
" join fetch o.delivery d" +
" join fetch o.orderItems oi" +
" join fetch oi.item i", Order.class)
.getResultList();
}
}
JPA의 핵심인 EntityManager
와 EntityManagerFactory
라이브러리는 Entity CRUD를 처리하지만,
EntityManager를 직접 작성하는 경우는 거의 X
주로 Repository Interface만 사용 O
→ 여기서 말하는 Repository interface 가 Spring Data JPA
이다.
Repository Interface 의 장점
- EntityManager를 직접 작성하지 않아도, DB에 Entity의 CRUD 처리된다.
→ Repository Interface 에는 EntityManager 가 포함되어 있기 때문- @Repository 를 추가하지 않아도, Bean 으로 자동 등록된다.
Spring Data JPA를 사용하지 않는다면,
클래스에 @Repository를 작성하고 JPA를 적용한 다음 EntityManager의 API 를 직접 호출해야
Entity에 대한 CRUD가 처리된다.
주의!
JPA 와 Spring Data JPA 는 완전히 같은 개념 X
참고: JPA (Java Persistence API) - 3) Spring Data JPA
package org.springframework.data.jpa.repository.support;
import ...
@Repository
@Transactional(readOnly = true) // SimpleJpaRepository에 구현된 API가 읽기 전용 트랜잭션을 통해 실행된다.
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {
private final JpaEntityInformation<T, ?> entityInformation;
private final EntityManager em;
private final PersistenceProvider provider;
public SimpleJpaRepository(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {...}
@Override
public Optional<T> findById(ID id) {...}
@Override
public List<T> findAllById(Iterable<ID> ids) {...}
@Override
public long count() {...}
@Transactional // SAVE 관련 API를 사용할 때는 읽기 전용 트랜잭션이 아닌 자동으로 Flush가 호출되는 일반 트랜잭션이 생성된다.
@Override
public <S extends T> S save(S entity) {...}
@Override
@Transactional // DELETE 관련 API를 사용할 때는 읽기 전용 트랜잭션이 아닌 자동으로 Flush가 호출되는 일반 트랜잭션이 생성된다.
@SuppressWarnings("unchecked")
public void delete(T entity) {...}
Repository Interface의 기본 구현체
Spring Data JPA 가 제공하는 가장 많은 기능을 가지고 있음
가장 밑단에 있는 클래스
public MemoResponseDto createMemo(MemoRequestDto requestDto) {
// RequestDto -> Entity
Memo memo = new Memo(requestDto);
// DB 저장
Memo saveMemo = memoRepository.save(memo);
// Entity -> ResponseDto
MemoResponseDto memoResponseDto = new MemoResponseDto(saveMemo);
return memoResponseDto;
}
public List<MemoResponseDto> getMemos() {
// DB 조회
return memoRepository.findAll().stream().map(MemoResponseDto::new).toList();
}
private Memo findMemo(Long id) {
return memoRepository.findById(id).orElseThrow(() ->
new IllegalArgumentException("선택한 메모는 존재하지 않습니다.")
);
}
@Transactional
public Long updateMemo(Long id, MemoRequestDto requestDto) {
// 해당 메모가 DB에 존재하는지 확인
Memo memo = findMemo(id);
// memo 내용 수정
memo.update(requestDto);
return id;
}
public Long deleteMemo(Long id) {
// 해당 메모가 DB에 존재하는지 확인
Memo memo = findMemo(id);
// memo 삭제
memoRepository.delete(memo);
return id;
}
public Long deleteMemo(Long id) {
// 해당 메모가 DB에 존재하는지 확인
Memo memo = findMemo(id);
// memo 삭제
memoRepository.delete(memo);
return id;
}
Hibernate 의 SessionFactory, Session, Transaction Interface 는
JPA Interface인 EntityManagerFactory, EntityManager, EntityTransaction를 상속받아 구현되어있다.
package org.hibernate;
public interface SessionFactory extends EntityManagerFactory, HibernateEntityManagerFactory … {}
public interface Session extends SharedSessionContract, EntityManager … {}
public interface Transaction extends EntityTransaction {}
JPA 를 구현한 구현체
→ Hibernate 외에도 여러 ORM Framework가 존재하나(Hibernate, EclipseLink, DataNucleus 등...), Hibernate 가 주로 사용된다)