반응형
JpaRepository란?
- Spring Framework에서 제공하는 JpaRepository를 제공해준다.
- JpaRepository는 인터페이스이다.
- JpaRepository는 자동으로 클래스를 만들고 Bean을 생성해준다.
- CRUD처리를 위한 공통 인터페이스 제공
@Repository
public interface MemberRepository extends JpaRepository<Member, Integer> {
}
- <>안에는 엔티티 클래스 이름과 ID 필드 타입이 지정된다. 주의할 점은 "기본형의 경우, 래퍼 클래스를 지정한다는 점이다. 위에 코드에 보면 기본형 int가 래퍼 클래스를 지정하여 Integer로 해준걸 확인 할수가 있다.
- 또 하나 주의해야 할 것은 어노테이션이다. 클래스의 선언 앞에 @Repository라는 어노테이션이 붙어져 있다. 그러면 이 인터페이스가 JpaRepository임을 나타낸다. 이는 반드시 붙여 두어야 한다.
EntityManager
- EntityManager는 영속성 컨텍스트이다
- 영속성 컨텐스트란?
- 엔티티를 영구 저장하는 환경을 뜻한다.
- 애플리케이션과 데이터베이스 사이에서 객체를 보관하는 가상의 데이터베이스 같은 역할을 한다.
- 엔티티 매니저를 통해 엔티티를 저장하거나 조회하면 에티티 매니저 영속성 컨텍스트에 엔티티를 보관하고 관리한다.
em.persist(member);
엔티티 매니저를 사용해 엔티티를 영속성 컨텍스트에 저장한다는 의미이다
영속성 컨텍스트의 특징
- Java 영역에서 데이터를 관리하여 DB접근을 최적화하는 역할을 담당한다.
- 엔티티 매니저를 생성할 때 하나 만들어진다.
- 엔티티 매니저를 통해서 영속성 컨텍스트에 접근하고 관리할 수 있다.
생명주기
엔티티는 4가지 상태가 존재한다
1. 비영속 : 영속성 컨텍스트와 연관이 없는 상태
2. 영속 : 영속성 컨텍스트에서 관리 중인 상태
3. 준영속 : 영속성 컨텍스트에 저장되어 있었으나 분리된 상태
4. 삭제 영속성 컨텍스트에서 완전히 삭제된 상태
영속
- EntityManager를 통해 데이터를 영속성 컨텍스트에 저장했다.
- JPA는 일반적으로 id 필드가 존재하지 않으면 예외를 뱉어내는데, 영속 상태의 엔티티를 관리하기 위해서다.
- id로 데이터를 관리하기 때문에 꼭 필요한 것이다.
이 상태가 되면 몇 가지의 장점을 갖게 된다.
- 1차 캐시
- em.find(key)를 호출하면 영속성 컨텍스트에 캐시된 데이터를 먼저 찾는다.
- 캐시된 데이터가 없다면 DB에 접근하여 데이터를 로드하고 1차 캐시 데이터에 저장한다.
- 1차 캐시의 존재로 Java 영역에서 REPEATABLE READ 등급의 트랜잭션 격리 수준을 활용한다.
- 동일성 보장
- JPA를 통해 불러온 데이터는 모두 캐시 데이터에 저장되기 때문에 같은 id를 가진 데이터는 같은 데이터이다.
- 일반적으로 Java에서 '같다'라는 기준은 Identity(hashcode) / Equality(equals)이다.
SomeEntity a = em.find(SomeEntity.class, "1"); SomeEntity b = em.find(SomeEntity.class, "1"); // a == b : true (Identity) // a.equals(b) : true (Equality)
- JPA를 통해 불러온 데이터는 모두 캐시 데이터에 저장되기 때문에 같은 id를 가진 데이터는 같은 데이터이다.
- 트랜잭션 지원하는 쓰기 지연
- Transaction이 시작된 이후 JPA가 생성한 쿼리는 모두 쓰기 지연 저장소에 저장된다.
- commit이 수행되면 저장된 모든 쿼리를 실행한다.
- 변경 감지
- SQL을 직접 활용하여 개발하면 update문을 수행할 때 매우 귀찮은 점이 있다.
- 컬럼 1개, 2개, 3개, ... N개를 수정해야 할 때를 모두 쿼리로 작성해야 하는 것이다.
- 이렇게 되면 비즈니스 로직은 SQL에 의존할 수밖에 없다.
- JPA는 데이터를 저장하기 전 영속성 컨텍스트에 저장된 데이터가 있는지 확인한다.
- 동일 데이터가 존재하면 update, 없으면 insert를 수행한다(upsert).
- JPA가 실제로 수행하는 쿼리는 모든 컬럼을 변경한다.
- 컬럼이 굉장히 많은(30개 이상) 테이블이 아니면 성능에 크게 영향을 미치지 않는다.
- 엔티티 클래스에 @DynamicUpdate를 붙여주면 SET절에 변경된 데이터만 삽입된다.
- 지연 로딩
준영속
영속 상태의 엔티티를 detach 시키거나 영속성 컨텍스트 자체가 초기화 / 종료되면 컨텍스트 내부의 모든 데이터는 준영속 상태가 된다.
// 1.
em.detach(someEntity);
// 2.
em.close();
// 3.
em.clear();
삭제
em.remove(someEntity);
플러시
(flush)플러시를 수행하면 아래 순서대로 동작한다.
- 데이터의 변경을 감지한다.
- 생성된 쿼리를 쓰기 지연 저장소에 등록한다.
- commit되면 저장되어 있던 쿼리를 모두 수행한다.
em.flush()를 활용하면 직접 플러시할 수 있다.
- 영속성 컨텍스트의 변경 내용을 DB에 반영하는 절차이다.
- 엔티티를 영속성 컨텍스트와 DB 양쪽에서 모두 삭제한다.
- 관리되지는 않는 상태이지만 JPA의 지원을 받지 못할 뿐, 정상적인 데이터를 갖는 인스턴스이다.
- 원래 영속 상태였으나 영속성 컨텍스트에서 분리되어 더 이상 관리하지 않는 데이터가 된 상태이다.
참고자료
https://private-space.tistory.com/81
'Spring' 카테고리의 다른 글
객체 지향 프로그래밍 (0) | 2022.06.01 |
---|---|
Spring 과 Spring boot (0) | 2022.06.01 |
엔티티 설계 주의점 (0) | 2021.11.21 |
Maven vs Gradle (0) | 2021.11.05 |
Spring 이란? (0) | 2021.07.14 |