본문 바로가기

SpringBoot

ch4 02. 엔티티 매니저 팩토리와 엔티티 매니저

 

1. EntitiyManager와 EntityManagerFactory

- EntityManagerFactory : EntitiyManager를 생성. 애플리케이션에 하나

- EntityManager : Entity를 저장 관리. 사용자당 하나

IF) 여러 사람이 써야한다면 EntityManager를 하나 더 만들어서 따로 사용해야한다. (공유 불가)

 

- 사용자는 직접 DB에 명령내리는 대신, Entity로만 작업

- 저장은 persist(), 조회는 find(), 삭제는 remove(), 변경은 Entity의 setter를 이용

우리가 직접 SQL을 작성하지 않고 메소드만 호출하면 끝난다!

 

 

2. Entity 클래스의 작성

- Entity클래스 : DB테이블의 한 행(row)을 정의한 것

- Entity클래스를 작성하고 @Entity를 붙인다. 

- Entity클래스에서 키(PK)로 사용할 속성에 @Id를 붙인다. 

 

 

 

3. Entity클래스의 작성을 위한 애너테이션

애너테이션 설 명(기본값)
@Entity Entity클래스에 사용
@Id DB테이블의 PK로 사용할 속성에 사용
@Table DB테이블에 대한 세부 정보 지정에 사용
name - 테이블 이름을 직접 지정
catalog - DB카탈로그 지정
schema - DB스키마 지정
uniqueContraint - 유일값 제약조건 지정
@Column name - 컬럼 이름(속성이름)
unique - 유일 값 제약조건 추가(false)
nullable - null입력 허용(true)
insertable - insert문에 포함여부(true)
updateable - update문에 포함여부(true)
columnDefinition - 직접 컬럼 속성 기술
length - 문자열의 길이(255)
precision - 실수의 정밀도(0)
scale - 실수의 소수점 자리수(0)
애너테이션 설 명
@Enumerated enum타입인 속성에 사용
@Temporal java.util.Data - 타입의 날짜 맵핑에 사용
TemporalType.DATE - 날짜만
TemporalType.TIME - 시간만
TemporalType.TIMESTAMP - 날짜&시간
@Transient 테이블의 컬럼에서 제외할 속성에 사용
@Generated 자동 번호 생성을 적용할 속성에 사용
strategy - 자동 번호 생성 전략을 선택
generator - 이미 생성된 키 생성기를 참조

GenerationType.TABLE - DB테이블 사용
GenerationType.SEQUENCE - 시퀀스(Oracle) 사용
GenerationType.IDENTITY - IDENTITY(MySQL)사용
GenerationType.AUTO - DB에 따라 자동선택

 

 

4. EntityTransaction

Hibernate가 자동으로 SQL문을 만들어준다. ?에는 입력한 값들이 들어간다.(PreparedStatement - 성능 & 보안)

커밋하면 작업한 내용이 반영된다.

 

실제로는 try~catch로 감싸줘야 한다. 

try {
	tx.begin(); // 트랜잭션을 시작
    entityManager.persist(user); // User객체를 저장
    tx.commit(); // 트랜잭션을 종료(작업 내용을 DB에 반영)
} catch(Exception e) {
	tx.rollback(); // 트랜잭션을 종료(작업 취소)
} finally {
	entityManager.close();
}

 

 

 

5. Transaction이란?

- 더이상 나눌 수 없는 작업의 단위

- 계좌 이체의 경우, 출금과 입금이 하나의 Tx로 묶여야 됨. 

- '모'아니면 '도'. 출금과 입금이 모두 성공하지 않으면 실패. 

 

 

 

6. 커밋(commit)과 롤백(rollback)

- 커밋(commit) : 작업 내용을 DB에 영구적으로 저장

- 롤백(rollback) : 최근 변경사항을 취소(마지막 커밋으로 복귀)

 

 

 

7. PersistenceContext = PC = 저장공간

- Entity를 저장하는 공간. persist(entity)는 entity를 영속 상태로 변경

- PersistenceContext는 EntityManager마다 하나씩 가지고 있다. 

 

처음에 entity를 생성하면 '비영속 상태'로 PersistenceContext에 저장이 안됐다는 뜻이다. 

이걸 EntityManager.persist(entity)를 호출하면 관리되지 않던 엔티티 객체가 '영속 상태'가 되어 PersistenceContext에 

저장되는 것이다.

 

만약, 제거하고 싶다면 remove()를 호출해서 엔티티가 영속 상태에 있다가 비영속 상태(관리되지 않는 상태)로 바뀐다. 

 

 

- Entity를 저장하는 공간. persist(entity)는 entity를 영속 상태로 변경

- 캐시, 변경 감지, 지연 로딩, 트랜잭션 지원

flush() 명령을 주면 SQL로 전송이 된다. 그 전까지는 DB에 SQL문이 전송이 안된다. 

 

 

8. flush()와 tx.commit()

- persist()는 Entity를 영속 상태로 바꾸고, SQL 저장소에 INSERT문을 저장

- flush()는 SQL저장소에 누적된 SQL을 DB로 전달. tx.rollback() 가능

- tx.commit()은 작업 내용을 DB에 영구 반영(flush() 자동 호출). tx.rollback() 불가

persist()를 호출하면 엔티티가 영속 상태가 되고 PersistenceContext에 있는 SQL저장소에 INSERT문이 등록된다. 

 

 

IF) 엔티티에 setter를 호출해서 속성 값을 바꾸면 SQL저장소에 UPDATE문장이 저장된다. 

영속 상태에 있는 값을 변경! 모든 컬럼이 update문에 포함되어 있다. 

 

 

 

9. PersistenceContext의 캐시

- 실제 Entity가 저장되는 공간(Map). Entity의 @Id컬럼을 Key로 사용

 

실제 엔티티가 저장되는 공간이 '캐시'이다. PersistenceContext안에 엔티티가 맵 형태로 저장이 된다. 

 

- 캐시에서 Entity를 먼저 조회. 캐시에 없을 때만 DB에서 조회.

키가 aaa인 사람을 찾는다고 하면 캐시에서 먼저 찾는다. 찾으면 객체의 주소를 반환해서 User 엔티티에 접근할 수 있게

되므로 DB까지 갈 필요가 없다. (조회가 빠름)

 

키가 bbb인 사람을 찾는다고 할 때 캐시에서 조회하니 데이터가 없을 경우 엔티티 매니저가 DB에서 가져와서 
캐시에 저장한다. 그러면 없던 데이터가 캐시에 생기고 반환한 주소를 사용자쪽에서 해당 주소를 가지고 엔티티를 
사용한다.  

 

clear()메소드를 호출하면 캐시를 다 비운다. 그러면 PersistenceContext에 있던 캐시가 다 비워지게 된다.