인프런 김영한님 강의를 보고 정리한 글입니다
EntityManager.persist(entity);
엔티티 매니저
를 이용해야 한다.//객체를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
//객체를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername(“회원1”);
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
//객체를 저장한 상태(영속)
em.persist(member);
//특정 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태
em.detach(entity)
// 영속성 컨텍스트를 완전히 초기화
em.claer()
// 영속성 컨텍스트를 종료
em.close()
//객체를 삭제한 상태(삭제)
em.remove(member);
1차 캐시
// 엔티티를 생성한 상태 (비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
// 엔티티를 영속, 1차 캐시에 저장됨
em.persist(member);
// 1차 캐시에서 조회
Member findMember = em.find(Member.class, "member1");
// 1차 캐시에 없다면 DB 조회 후 1차 캐시에 저장해서 반환
Member findMember2 = em.find(Member.class, "member2");
동일성(identity) 보장
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");
System.out.println(a == b); //동일성 비교 true
트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.
transaction.begin(); // 트랜잭션 시작
em.persist(memberA);
em.persist(memberB);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
transaction.commit(); // 트랜잭션 커밋
버퍼링
기능을 사용할 수 있음변경 감지 (dirty checking)
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // 트랜잭션 시작
// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");
// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);
//em.update(member) 이런 코드가 있어야 하지 않을까? 답: 필요없음
transaction.commit(); // 트랜잭션 커밋
트랜잭션
작업 단위가 중요하며, 커밋 직전에만 동기화 하면 됨// (1) 직접 호출 -- 테스트할 때 주로 사용
em.flush();
// (2) 트랜잭션 커밋 시 플러시 자동 호출
transaction.commit();
// (3) JPQL 쿼리 실행 시 플러시 자동 호출
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
// 이 상태에서 조회 하면 insert 쿼리가 날아가기 전이기 때문에 조회 안 됨
// 이렇게 엉키는 걸 막기 위해서 JPQL 실행 시 무조건 flush가 호출됨
query = em.createQuery("select m from Member m", Member.class);
List<Member> members= query.getResultList();
// 커밋이나 쿼리를 실행할 때 플러시 (기본값) -- 권장
em.setFlushMode(FlushModeType.AUTO)
// 커밋할 때만 플러시 -- 쿼리를 실행할 때는 flush가 안 된다는 뜻, 테스트 시 용이
em.setFlushMode(FlushModeType.COMMIT)