JPA
관계형 데이터베이스 SQL 테이블과 객체 지향 프로그래밍 (자바)간의 매핑을 자동으로 해주는
ORM 을 사용한 인터페이스이다.
영속성 컨텍스트
엔티티를 저장하는 논리적인 개념이다.
애플리케이션(자바) ~ DB 사이에서 객체를 보관하는 가상의 DB 역할로
Buffer을 이용해 flush할 때 DB에 반영한다.
장점
1차 캐시
엔티티 조회시
1차 캐시에서 조회
1차 캐시에 없을 경우 DB에서 조회 (1차 캐시에 저장 후 반환)
EM은 트랜잭션 단위이기에 트랜잭션이 끝나면 1차 캐시도 삭제됨
1차 캐시는 성능 향상도 있지만 매커니즘적인 장점이 큼
(2차 캐시는 애플리케이션 전체에서 공유하는 캐시이다)
영속성 엔티티의 동일성 보장 (1차 캐시)
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");
System.out.println(a == b) // 동일성 보장
Mybatis에서는 동일성이 보장이 안 됐으나
JPA는 1차 캐시에있는 같은 엔티티를 반환하여 동일성을 보장한다.
쓰기 지연
쓰기 지연 SQL 저장소에 모았다가
트랜잭션을 커밋하는 순간 DB에 SQL을 보냄
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.
transaction.begin(); // [트랜잭션] 시작
em.persist(memberA);
em.persist(memberB);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
transaction.commit(); // [트랜잭션] 커밋
더티 체킹 (엔티티 변경감지)
JPA에서는 수정할 때 따로 업데이트나 저장을 할 필요가 없다
플러시 시점에 엔티티와 스냅샷을 비교해서 바뀐 엔티티 찾는데
바뀐 엔티티가 있으면→ update 쿼리를 쓰기 지연 저장소에 저장 → 디비에
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(); // [트랜잭션] 커밋
엔티티의 생명주기
비영속
객체만 생성하고 엔티티와 연결하지 않은 것
영속 = @Id로 키값을 매핑해줘야됨
객체를 생성하고 저장한 상태
영속성 컨텍스트가 관리하는 엔티티 (1차캐시/ 쓰기지연 저장소에 있는 상태)
JPA가 관리하는 상태로 1차 캐시에 있는 상태이다.
em.persist(member);
em.find();
//객체를 생성만 한 상태(비영속)
Member member = new Member();
member.setId("member1");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
//객체를 저장한 상태(영속)
em.persist(member);
준영속
엔티티가 영속성 컨텍스트에서 분리 된 상태
1차 캐시와 쓰기 지연 SQL 저장소에서 제거된 상태이기 때문에
트랜잭션 커밋할 때 쿼리 생성이 안 된다.
em.detached();
삭제
em.remove();
상태 변화
비영속 → 영속 → 삭제
영속 → 준영속
플러시
영속성 컨텍스트의 변경내용을 DB에 동기화
em.getTransaction().begin();
Employee emp = new Employee();
emp.setName("Jane Smith");
emp.setSalary(60000);
em.persist(emp);
em.flush(); // 영속성 컨텍스트를 데이터베이스와 동기화
em.getTransaction().commit();
em.close();
플러시 모드
FlushModeType.AUTO (기본값)
기본 플러시 모드로, 트랜잭션 커밋 시 자동으로 플러시된다.
FlushModeType.COMMIT
트랜잭션이 커밋될 때만 플러시가 수행됩니다. 이 모드는 명시적으로 flush()를 호출해야 변경 사항이 데이터베이스에 반영된다.
웬만하면 AUTO 사용함
1차 캐시랑은 상관없이 쓰기 지연 저장소를 한 번에 디비에 반영하는 과정
1. 변경 감지
2. 수정된 엔티티를 쓰기 지연 SQL 저장소에 등록
3. 저장소의 모아둔 쿼리를 한 번에 DB로 보냄
em.detach(entity)
특정 엔티티만 준영속 상태로 바꾼다
em.clear()
1차 캐시를 지우고 영속성 컨텍스트를 처음부터 만든다
em.close()
영속성 컨텐츠를 닫아 관리를 종료한다.
EntityManager을 사용한 후에는 반드시 close를 호출하여 트랜잭션을 명확하게 종료해야한다.
안 그러면 데이터베이스에 대한 변경이 불완전하게 처리될 수 있
'CS > SPRING' 카테고리의 다른 글
JPA 필드와 컬럼 매핑 (0) | 2024.08.12 |
---|---|
JPQL과 SQL의 차이점 (0) | 2024.08.12 |
JPA를 사용한 간단한 CRUD 구현 (0) | 2024.08.12 |
serviceImpl 을 사용하는 이유 (1) | 2024.07.23 |
웹서버 WAS, SERVLET (0) | 2024.07.08 |