1) Entity
: JPA에서 관리되는 클래스. 즉, 객체를 의미
- Entity 클래스는 DB의 테이블과 매핑되어 JPA에 의해 관리됨.
Annotation
@Entity
: JPA가 관리할 수 있는 Entity 클래스로 지정하는 annotaion
@Table
: 매핑할 테이블 지정
@Id
: table의 기본키를 지정해주는 annotation
- 영속성 컨텍스트에서 entity를 구분할 때 사용
- 기본키를 넣어주지 않으면 오류 발생
@GeneratedValue
: 기본 키 생성을 DB에 위임 가능
- (strategy = GenerationType.IDENTITY)
: DB가 자동으로 ID를 생성하도록 함
@Column
- nullable
: null 허용 여부 (default : true) - unique
: 중복 허용 여부 (false일 때 중복 허용. default: false) - length
: 컬럼 길이 지정 (default: 255)
2) 영속성 컨텍스트
: Entity 객체를 효율적으로 쉽게 관리하기 위해 만들어진 공간
- CRUD과정을 효율적으로 처리하기 위해 JPA는 영속성 컨텍스트에 Entity객체들을 저장하여 관리하면서 DB와 소통함
- 영속성 컨텍스트에 접근하여 Entity 객체들을 조작하기 위해서는 EntityManager가 필요
- 개발자들은 EntityManager를 사용해 Entity를 CRUD 할 수 있음.
- EnityManage는 EntityManagerFactory를 통해 생성
3) EntityManagerFactory
: 한 DB당 하나만 생성되어 애플리케이션이 동작하는 동안 사용됨
- EntityManagerFactory를 만들기 위해서는 DB에 대한 정보를 전달해야 됨.
- /resources/META-INF/ 위치에 persistence.xml 파일을 만들어 정보를 넣어두면 정보 전달할 수 있음
- /resource/META-INF/ 위치에 persistence.xml 파일을 만들어 정보를 넣어두면 해당 정보를 읽음.
- xml파일의 정보를 토대로 Persistence라는 클래스에 의해서 EntityManagerFactory가 만들어짐
- EntityManagerFatory에 의해 EntityManager 생성
4) 트랜잭션
: DB 데이터들을 안전하게 관리하기 위해 생겨난 개념
- 여러 개의 SQL이 하나의 트랜잭션에 포함될 수 있다는 것이 가장 큰 특징
- 모든 SQL이 성공적으로 수행되면 DB에 영구적으로 반영.
SQL 중 단 하나라도 실패한다면 모든 변경 되돌림.
- 모든 SQL이 성공적으로 수행되면 DB에 영구적으로 반영.
- 영속성 컨텍스트에 Entity 객체를 저장했다고 해서 DB에 바로 반영되지 ❌
- 영속성 컨텍스트로 관리하고 있는 변경이 발생한 객체들의 정보를 ActionQueue에 전부 가지고 있다가 마지막에 한 번에 요청해 변경 반영
@Test
@DisplayName("EntityTransaction 성공 테스트")
void test1() {
EntityTransaction et = em.getTransaction(); // EntityManager 에서 EntityTransaction 을 가져옵니다.
et.begin(); // 트랜잭션을 시작합니다.
try { // DB 작업을 수행합니다.
Memo memo = new Memo(); // 저장할 Entity 객체를 생성합니다.
memo.setId(1L); // 식별자 값을 넣어줍니다.
memo.setUsername("Robbie");
memo.setContents("영속성 컨텍스트와 트랜잭션 이해하기");
em.persist(memo); // EntityManager 사용하여 memo 객체를 영속성 컨텍스트에 저장합니다.
et.commit(); // 오류가 발생하지 않고 정상적으로 수행되었다면 commit 을 호출합니다.
// commit 이 호출되면서 DB 에 수행한 DB 작업들이 반영됩니다.
} catch (Exception ex) {
ex.printStackTrace();
et.rollback(); // DB 작업 중 오류 발생 시 rollback 을 호출합니다.
} finally {
em.close(); // 사용한 EntityManager 를 종료합니다.
}
emf.close(); // 사용한 EntityManagerFactory 를 종료합니다.
}
- et.begin()
: 트랜잭션을 시작하는 명령어 - et.commit()
: 트랜잭션의 작업들을 영구적으로 DB에 반영하는 명령어 - et.rollback()
: 오류가 발생했을 때 트랜잭션의 작업을 모두 취소하고 이전 상태로 되돌리는 명령어
- Entity 클래스는 DB에 매핑이 되는 것이기 때문에 조심스럽게 다뤄야 함.
그러므로 setter는 필요한 곳에만 달아줘야 함.
5) 영속성 컨텍스트의 기능
1차 캐시
- 영속성 컨텍스트는 내부적으로 "캐시 저장소"라는 것을 가지고 있음
- 저장하는 Entity 객체들이 1차캐시(캐시 저장소)에 저장됨
- 캐시 저장소는 Map 자료구조 형태로 되어있음.
- key ➡️ @Id로 매핍한 기본키(식별자 값) 저장
- value ➡️ 해당 Entity 클래스의 객체 저장
- 영속성 컨텍스트는 캐시 저장소 Key에 저장한 식별자값을 사용하여 Entity 객체를 구분하고 관리
- 1차 캐시가 있어 DB 조회 횟수가 줄어듦.
- DB row 한 개당 객체 한 개가 사용되는 것을 보장함.
영속성 컨텍스트의 캐시저장소 활용
- Entity 저장
- em.persist(memo); 메서드가 호출되면 memo Entity 객체를 캐시 저장소에 저장.
- Entity 조회
- 캐시 저장소에 조회하는 Id가 존재하지 않은 경우
- 캐시 저장소 조회
- DB SELECT 조회 후 캐시 저장소에 저장
- 캐시 저장소 조회
- 캐시 저장소에 조회하는 Id가 존재하는 경우
em.find(memo.class, 1); 호출 시 캐시 저장소에 식별자 값이 1이면서 Memo Entity 타입인 값이 있는지 조회 후 값이 있다면 해당 Entity 객체 반환
- 캐시 저장소에 조회하는 Id가 존재하지 않은 경우
- Entity 삭제
- 삭제할 Entity 조회 후 캐시 저장소에 없다면 DB에 조회해서 저장
- em.remove(entity); 호출시 삭제할 Entity를 DELETED 상태로 만든 후 프랜잭션 commit후 Delete SQL이 DB에 요청 됨.
- 삭제할 Entity 조회 후 캐시 저장소에 없다면 DB에 조회해서 저장
flush()
: 영속성 컨텍스트의 변경 내용들을 DB에 반영하는 역할 수행
(쓰기 지연 저장소의 SQL들을 DB에 요청하는 역할)
- 트랜잭션 commit 후 추가적으로 em.flush(); 메서드를 호출
변경 감지(Dirty Checking)
: 변경하고 싶은 데이터가 있다면 데이터를 조회하고 해당 Entity 객체의 데이터를 변경하면 자동으로 Update SQL이 생성되고 DB에 반영되는 것
- 영속성 컨텍스트에 저장된 Entity가 변경될 때마다 Update SQL이 쓰기 지연 저장소에 여러 번 요청해야하기 때문에 저장되면 비효율적이기 때문에 변경 감지 과정을 통해 이러한 문제 해결
'내일배움캠프(Sparta) > Spring' 카테고리의 다른 글
[Spring] SpringBoot의 JPA (0) | 2023.11.07 |
---|---|
[Spring] Entity의 상태 (0) | 2023.11.07 |
[Spring] ORM / JPA / Hibernate (0) | 2023.11.07 |
[Spring] IoC / DI / Bean (0) | 2023.11.07 |
[Spring] 3 Layer Architecture (0) | 2023.11.03 |