JPA 3rd Step

최보현·2022년 8월 27일
0

JPA

목록 보기
2/10
post-thumbnail

자바 ORM 표준 JPA 프로그래밍 - 기본편 - sec03
출처 : JPA 기본편

영속성 관리

JPA에서 가장 중요한 2가지
1. 객체와 관계형 데이터베이스 매핑하기
2. 영속성 컨텍스트

영속성 컨텍스트

엔티티를 영구 저장하는 환경 이라는 뜻
EntityManager.persist(entity);

이는 논리적인 개념으로 눈에 보이지는 않음
엔티티 매니저를 통해서 영속성 컨텍스트에 접근함
J2SE 환경

J2EE, 스프링 프레임워크 같은 컨테이너 환경

엔티티의 생명주기

비영속

영속성 컨텍스트와 전혀 관계가 없는 새로운 상태

등록 & 비영속 상태
Member member = new Member();
member.setId(101L);
member.setName("HelloJPA");

영속

영속성 컨텍스트에 관리되는 상태 => 객체를 저장한 상태

영속 상태(영속성 컨텍스트를 통해서 관리됨 => 실질적으로 db저장되는 것은 아님)
System.out.println("==== BEFORE ====");
em.persist(member); //member를 저장함
System.out.println("==== AFTER ====");

준영속

영속성 컨텍스트에 저장되었다가 분리된 상태

회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태
//특정 엔티티만 준영속 상태로 전환
em.detach(member);

detach는 영속성 컨텍스트를 관리하지 말라고 끊어내는 것, 이렇게 되면 영속성 컨텍스트가 제공하는 기능 사용 불가

//영속성 컨텍스트를 완전히 초기화
em.clear()

//영속성 컨텍스트를 종료
em.close()

삭제

삭제된 상태

객체를 삭제한 상태
em.remove(memeber);

영속성 컨텍스트의 장점

  • 1차 캐시
//비영속 상태
Member member = new Member();
member.setId(101L);
member.setName("HelloJPA");

//영속 상태 => 1차 캐시에 저장됨
em.persist(member); //member를 저장함

//1차 캐시에서 조회
Member findMember = em.find(Member.class, 101L);

예를 들어보자면,

만약에, 우리가 저장하지 않은 것을 조회할 때는 어떻게 될까?
DB에서 조회를 한다
Member findMember = em.find(Member.class, 102L);

+) 1차캐시는 데이터베이스 안에서만 사용됨, 2차 캐시는 모두에게 공유되는 것

  • 동일성 보장
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");

System.out.println(a == b); //동일성 비교 true

1차 캐시로 반복 가능한 읽기(REPEATABLE READ) 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공

  • 트랜잭션을 지원하는 쓰기 지연
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//엔티티 매니저는 데이터 변경시 트랜잭션을 해야 함!!

//트랜잭션 시작
transaction.begin(); 

em.persist(memberA);
em.persist(memberB);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않음

//커밋하는 순간 데이터베이스에 INSERT SQL을 보냄
//트랜잭션 커밋
transaction.commit(); 

영속성이 부여되는 과정

트렌젝션 커밋의 과정

  • 변경 감지
    만약에 우리 수정을 한 경우에는 어떻게 될까?
//수정
Member findMember = em.find(Member.class, 1L); //멤버 조회
findMember.setName("HelloJPA"); 

수정은 따로 저장을(em.persist) 하지 않아도됨

따로 update같은 코드가 없더라도 알아서 변경을 감지에서 바꿔줌, 진짜 똑순이

  • 지연 로딩

플러시

영속성 컨텍스트의 변경 내용을 데이터베이스에 반영
영속성 컨텍스트를 비우는 것이 아닌, 변경 내용을 데이터베이스에 동기화하는 역할
트랙잭션 커밋 직전에만 동기화하면 됨

플러시가 발생하는 모먼트

  • 변경 감지
  • 수정된 엔티티 쓰기 지연 SQL 저장소에 등록
  • 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송(등록, 수정, 삭제 ~)

플러시하는 방법

  • em.flush() 직접 호출
  • transaction.commit() 플러시 자동 호출
  • JPQL 쿼리 실행 플러시 자동 호출
//JPQL 사용 방법(EX: 특정 조건을 건 전체 회원 조회)
List<Member> result = em.createQuery("select m from Member as m", Member.class)
         .setFirstResult(5)
         .setMaxResults(10) //5번부터 10번까지 가져와라
         .getResultList();

플러시 모드 옵션

em.setFlushMode(FlushModeType.~~~)

  • FlushModeType.AUTO
    커밋이나 쿼리를 실행할 때 플러시 (기본값)
  • FlushModeType.COMMIT
    커밋할 때만 플러시
profile
Novice Developer's Blog

0개의 댓글