JPA CRUD(+ 영속 컨텍스트)
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); // /persistence.xml => <persistence-unit name="hello">
EntityManager em = emf.createEntityManager(); //테이블 접근 시, 무조건 EntityManager 을 통해서 해야됨
EntityTransaction transaction = em.getTransaction(); //JPA 에서의 모든 데이터 변경을 EntityTransaction 으로 이루어짐
transaction.begin(); // 데이터베이스 transaction 을 시작
em.createQuery("delete from Member").executeUpdate(); //실행 할때마다 테이블의 모든 튜플들 삭제
transaction.commit();
//Create
Member memberA = new Member();
memberA.setId(1L);
memberA.setUsername("hello"); // Member 테이블에 저장할 튜플 생성
Member memberB = new Member();
memberB.setId(2L);
memberB.setUsername("helloB"); // Member 테이블에 저장할 튜플 생성
try {
transaction.begin(); // 데이터베이스 transaction 을 시작; 이전에 transaction.commit()을 했으면 다시 begin()을 해줘야 함
/**
* Member 테이블에 memberA && memberB 객체들 적재
*/
em.persist(memberA);
em.persist(memberB);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
}
//Remove
try {
transaction.begin(); // 데이터베이스 transaction 을 시작
/**
* Column id로 원하는 튜플을 찾아서 객체로 반환 받고, 해당 객체를 제거
*/
Member findMember = em.find(Member.class, 2L);
em.remove(findMember);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
}
//Update
try {
transaction.begin(); // 데이터베이스 transaction 을 시작
/**
* Column id로 원하는 튜플을 찾아서 객체로 반환 받고, 해당 객체의 값을 수정
*/
Member findMember = em.find(Member.class, 1L);
findMember.setUsername("helloJPA"); // persist()을 하지 않아도 자동으로 테이블이 업데이트 됨
transaction.commit(); //commit을 통해 변화 반영
} catch (Exception e) {
transaction.rollback();
}
try {
/**
* 쿼리문으로 원하는 값 찾기
* select *from member
*/
List<Member> memberList = em.createQuery("select m from Member as m", Member.class)
.getResultList();
for (Member mem : memberList) {
System.out.println("member.name = " + mem.getUsername());
}
} catch (Exception e) {
}
//항상 EntityManager랑 EntityManagerFactory를 close() 해줌
em.close();
emf.close();
-
persist(객체) 로 객체를 테이블에 저장
-
remove(객체) 로 객체를 테이블에서 제거
-
수정할 객체를 find(객체) 로 찾고, 반환 받은 객체의 값들을 수정하면 테이블에서도 수정이 됨
-
테이블에 튜플을 적재, 삭제, 수정 등을 하고 commit()을 해줘야 반영 됨
-
엔티티 매니저 팩토리는 하나만 생성해서 애플리케이션 전체에서 공유
-
엔티티 매니저는 쓰레드간에 공유X (사용하고 버려야 한다)
======= 영속 컨텍스트(EntityManager) 추가 설명 ======
EntityManager.persist(객체)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
//1차 캐시에 저장됨
em.persist(member);
EntityTransaction.commit()이 일어나기 전에는 엔티티가 DB에 저장되어 있지 않음. 1차 캐시에 엔티티가 저장되고, Buffer SQL 저장소에 INSERT INTO SQL문이 저장되어 있는 상태로 있음
EntityManager.find(객체)
Member findMember2 = em.find(Member.class, "member2");
//'member2' 가 1차 캐시에는 없고, 이미 DB에 저장되어 있는 상태
우선, 1차 캐시에서 엔티티가 있는지 조회하고, 없을 경우 DB를 조회함
DB에 엔티티가 있을 경우 1차 캐시에 반환해서 저장해줌
영속 엔티티의 동일성 보장
1차 캐시로 반복 가능한 읽기(REPEATABLE READ) 등급의 트랜잭
션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공.
EntityManager.persist(객체) -> EntityTransaction.commit()
em.persist(memberA);
em.persist(memberB);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
transaction.commit();
memberA 엔티티랑 memberB 엔티티가 1차 캐시에 저장되고, EntityTransaction.commit()이 일어나기 전까지는 DB에 저장되지 않음. 1차 캐시에 우선 저장되고, 각 엔티티에 대한 INSERT INTO SQL문이 Buffer SQL 저장소에 저장되어 있음.
commit()이 발생하면 Buffer SQL 저장소에 저장되어 있는 SQL문들이 실행됨
엔티티 수정
// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");
// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);
transaction.commit();
- setter로 엔티티를 수정 -> commit() 실행 하면 flush() 실행 -> 엔티티와 스냅샷을 모두 비교해서 수정된 스냅샷 찾음 -> UPDATE SQL문을 작성해서 Buffer SQL 저장소에 저장 -> Buffer SQL 저장소에 저장된 SQL문들 실행 -> DB에 수정된 부분 반영
Author And Source
이 문제에 관하여(JPA CRUD(+ 영속 컨텍스트)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@k_ms1998/JPA-CRUD저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)