JPA, Spring Data JPA, Hibernate

박영준·2023년 3월 25일
0

JPA

목록 보기
5/8

JPA

1. 정의

  • Application 과 JDBC 사이에서 동작한다.

  • Interface 의 모음

  • JPA 를 정의한 javax.persistence 패키지 대부분이 Interface 와 enum으로 구성
    → JPA 의 핵심인 EntityManager 도 interface 로 정의
    → JPA 에서 제공하는 EntityManager 로 DB 에 접근 가능

  • ORM 기술 표준

참고: JPA (Java Persistence API)

2. 사용법

EntityManager Interface

public interface EntityManager {

  public void persist(Object entity);
  public <T> T merge(T entity);
  public void remove(Object entity);
  public void flush();
  // more...
}

EntityManager에서 제공하는 API

@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();
    }
}
  • Spring Data JPA를 사용하지 않는다면, EntityManager에서 제공하는 API를 사용하면 된다.

Spring Data JPA

1. 정의

  • JPA의 핵심인 EntityManagerEntityManagerFactory 라이브러리는 Entity CRUD를 처리하지만,
    EntityManager를 직접 작성하는 경우는 거의 X
    주로 Repository Interface만 사용 O
    → 여기서 말하는 Repository interface 가 Spring Data JPA 이다.

    Repository Interface 의 장점

    1. EntityManager를 직접 작성하지 않아도, DB에 Entity의 CRUD 처리된다.
      → Repository Interface 에는 EntityManager 가 포함되어 있기 때문
    2. @Repository 를 추가하지 않아도, Bean 으로 자동 등록된다.
  • Spring Data JPA를 사용하지 않는다면,
    클래스에 @Repository를 작성하고 JPA를 적용한 다음 EntityManager의 API 를 직접 호출해야
    Entity에 대한 CRUD가 처리된다.

주의!
JPA 와 Spring Data JPA 는 완전히 같은 개념 X

참고: JPA (Java Persistence API) - 3) Spring Data JPA

2. SimpleJpaRepository

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 가 제공하는 가장 많은 기능을 가지고 있음

  • 가장 밑단에 있는 클래스

3. 적용

save

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;
}

findAll

public List<MemoResponseDto> getMemos() {
    // DB 조회
    return memoRepository.findAll().stream().map(MemoResponseDto::new).toList();
}

findById

private Memo findMemo(Long id) {
    return memoRepository.findById(id).orElseThrow(() ->
            new IllegalArgumentException("선택한 메모는 존재하지 않습니다.")
    );
}

update

@Transactional
public Long updateMemo(Long id, MemoRequestDto requestDto) {
    // 해당 메모가 DB에 존재하는지 확인
    Memo memo = findMemo(id);

    // memo 내용 수정
    memo.update(requestDto);

    return id;
}

delete

public Long deleteMemo(Long id) {
    // 해당 메모가 DB에 존재하는지 확인
    Memo memo = findMemo(id);

    // memo 삭제
    memoRepository.delete(memo);

    return id;
}

delete

public Long deleteMemo(Long id) {
    // 해당 메모가 DB에 존재하는지 확인
    Memo memo = findMemo(id);

    // memo 삭제
    memoRepository.delete(memo);

    return id;
}

Hibernate

  • 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 가 주로 사용된다)


참고: JPA와 Spring Data JPA의 차이 (feat. Hibernate)

profile
개발자로 거듭나기!

0개의 댓글