✅ 영속성 컨텍스트
: 자바에 등록된 엔티티를 영구 저장하는 환경
엔티티매니저 팩토리
는 하나만 생성해서 애플리케이션 전체에서 공유엔티티매니저
를 생성함엔티티매니저
를 생성시 한개의 영속성 컨텍스트
가 생성 ( 1 : 1 )엔티티매니저
로 영속성 컨텍스트
를 사용 (저장,조회,수정,삭제)엔티티매니저
는 쓰레드 간에 공유하지 않음 (사용하고 버려야함)EntityManager em = EntityManagerFactory.createEntityManager();
✅ 영속성 컨텍스트 장점
==
으로 비교해도 같음그럼 영속성이 정확히 무엇인지 알아보자
✅ 비영속성
: 그냥 일반적으로 객체가 만들어진 상태 (new 또는 builder로 객체가 생성된 상태)
Member member = new Member();
member.setId("member1");
member.setUsername("홍길동");
✅ 영속성
: 생성된 객체가 영속성 컨텍스트에 저장되어있는 상태 -> persist
, find
메소드 이용
EntityManager em = EntityManagerFactory.createEntityManager();
em.getTransaction().begin();
Member member = new Member();
em.persist(member); // 객체를 영속성 컨텍스트에 저장(영속) = 아직 쿼리를 보내지 않음 = 영속성컨테스트에만 저장
em.getTransaction.commit(); // 트랜잭션이 커밋하는 시점에 DB에 쿼리가 날라감 = DB에 INSERT됨
// update 문을 보내려는 경우
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // [트랜잭션] 시작
Member memberA = em.find(Member.class, "memberA"); // 영속 엔티티 조회
memberA.setUsername("hi"); // 영속 엔티티 데이터 수정 (한문장으로 update 가능)
transaction.commit(); // [트랜잭션] 커밋하는 순간에 DB에 UPDATE 쿼리 보냄
persist
: 새로운 엔티티를 영속성 컨텍스트에 추가하여, 트랜잭션 커밋 시 데이터베이스에 저장find
: 데이터베이스에서 특정 엔티티를 검색하고, 반환값이 null이면 해당 데이터가 없다는 의미✅ 준영속성
: 영속된 컨텍스트에 저장되어있다가 해제된 상태
// update 문을 보내려는 경우
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // [트랜잭션] 시작
Member memberA = em.find(Member.class, "memberA"); // 영속 엔티티 조회
em.detach(memberA); // memberA 엔티티를 영속성 컨텍스트에서 분리(준영속)
memberA.setUsername("hi");
transaction.commit(); // 이미 MemberA가 준영속 상태로 되었기 때문에, 커밋시점에 update문을 실행 x
준영속성
은 위에 영속성
과 다르게 update 쿼리가 보내지지 않는다
그 이유는 영속성 컨테스트에 있는 MemberA를 분리했기 때문
실제로는 직접 사용할 일은 없고, 웹 어플리케이션을 이해할 때 참고
준영속 상태로 만드는 방법은 다음과 같이 3개가 있다
detach()
: 특정 엔티티를 준영속 상태로 전환clear()
: 영속성 컨텍스트를 완전히 초기화close()
: 영속성 컨텍스트를 종료✅ 삭제
: 객체를 삭제한 상태
em.remove(member); // DB에 DELETE 쿼리가 COMMIT 시점에 나감
✅ JPA 구조
기존에는 CRUD 요청을 JDBC에다 했지만 JPA를 사용하면 JPA가 CRUD 요청을 한다
엔티티와 영속성 컨텍스트가 돌아가는 구조는 다음과 같다
(1) : Entity
어노테이션을 적용한 java 클래스의 객체를 생성 -> 비영속
상태임
(2) : EntityManager
객체를 사용해서 persist()
메소드를 이용하여 영속
상태로 만들어줌
(3) : 등록한 영속객체들은 영속성 컨텍스트
가 관리해줌
(4) : 트랜잭션을 커밋
하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 데이터 베이스에 반영
-> 자동으로 flush()
호출
✅ flush
: 영속성 컨테스트의 변경내용을 데이터베이스에 반영하는 작업
flush
가 호출되면
EntityManager em = EntityManagerFactory.createEntityManager();
em.getTransaction().begin();
Member member = new Member();
em.persist(member); // 객체를 영속성 컨텍스트에 저장(영속) = 아직 쿼리를 보내지 않음 = 영속성컨테스트에만 저장
// 원래는 트랜잭션 커밋되는 순간에 쿼리가 보내지지만, flush() 메소드를 호출하면
em.flush(); // 이 시점에서 쿼리보내짐
em.getTransaction.commit();
✅ 데이터베이스 스키마 자동생성
지난 장에 JPA를 설정할 때 아래와 같은 문구가 있을 것이다
이 설정은 개발할 때 테스트 용도로 편하게 사용하기 위해서 존재한다
<property name="hibernate.hbm2ddl.auto" value="create"/> // value에속성 넣음
hibernate.hbm2ddl.auto
옵션을 사용
@Entity
가 매핑되어있는 클래스을 가지고 자동 생성이 됨
운영에서는 사용하지 않고 개발할 때에만 테스트용도로 사용추천
다음은 스키마 자동생성 속성의 종류다
create
: 기존 테이블을 삭제 후 다시 생성함 (DROP + CREATE)create-drop
: create 속성과 동일하며, 종료시점에 테이블을 drop 시킴update
: 기존 테이블이 있다면 삭제하지 않고 변경한 부분을 update 시켜줌validate
: 엔티티와 테이블이 정상 매핑되어있는지 확인, 없으면 컴파일 오류 발생