// 엔티티를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
// 엔티티를 영속 - 1차 캐시에 저장됨
em.persist(member);
// 1차 캐시에서 조회
Member findMember = em.find(Member.class, "member1");
1차 캐시란 DB에서 가져오는 개념이 아니라 현재 실행되고 있는 Application 영속성 컨텍스트
영역에서 가져오는 것이다.
현재
영속성 컨텍스트
영역에 없는 데이터는1차 캐시
가 아닌 데이터베이스에서 가져온다.
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();
EntitiyTransaction transaction = em.getTransaction();
// 엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.
transaction.begin(); // [트랜잭션] 시작
em.persist(memberA);
em.persist(memberB);
// 다음 INSERT SQL을 데이터베이스에 보내지 않는다.
transaciton.commit(); // [트랜잭션] 커밋
// 커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
엔티티 등록을 할 때, 영속성 컨텍스트 내 쓰기 지연 SQL 저장소
가 있다는 것을 알게 되었다. 이곳에서 트랜잭션 관리 기능까지 갖추고 있음을 알 수 있다.
개인적으로 김영한님의 강의를 듣기전에 이 부분이 신기해서 강의를 수강하게 되었다.. ㅎㅎ
스터디를 진행하면서 update query가 없는 것을 보고 코드리뷰할 때, 여기에 update query가 없어도 되나요? 라고 물었는데 JPA J도 모르고 물은 질문이라 부끄러웠다 😓
그저 Model 객체가 변경된 것인데 DB에 변경까지 된다는게 신기했다.
EntityManager em = emf.createEntityManager();
EntitiyTransaction tx = em.getTransaction();
tx.begin(); // [트랜잭션] 시작
Member memberaA = em.find(Member.class, "memberA");
memberA.setUsername("update");
memberA.setAge(10);
// em.update(memberA); // 뭐 이런게 있어야 하지 않을까?
tx.commit(); // [트랜잭션] 변경감지가 적용되는 시점!!! (커밋 시점)
데이터베이스 트랜잭션을 커밋하면 flush함수가 호출되면서 엔티티와 스냅샷을 비교 한다. 변경이 있다면 UPDATE QUERY가 SQL 저장소에 저장이 되고 데이터베이스에 반영된다.
🎈 스냅샷
영속성 컨텍스트에 최초로 들어온 데이터
💡 플러시
영속성 컨텍스트 변경내용을 데이터베이스에 반영
- em.flush();
- 트랜잭션 commit();
- JPQL 쿼리 실행
지연 로딩은 좀 더 깊게 이해하게되면 작성할 예정
JPA는 결국 DB 데이터를 객체지향 관점으로 바꾸어서 사용할 수 있도록 도와주는 기술이다. 그 중간다리 역할을 하기 위해서 영속성 컨텍스트 개념이 너무나도 중요한 것이다.
예전에 MyBatis를 사용하여 .xml 을 왔다갔다 하며 개발했었는데 기존의 SQL 작성하여야 하는 프로세스의 단점을 커버하기 위해 나온듯 하다.
김영한님 ORM 표준 JPA프로그래밍 강의를 듣고 공부한 내용을 정리하고자 작성하였습니다. 문제가 될시 삭제하겠습니다. 🙂