서비스 & 리포지토리 개발(비즈니스 로직 수행) → 테스트 케이스 작성(검증) → 컨트롤러 & 뷰
Ex)
JPA(Java Persistence API)는 자바 진영의 ORM 기술 표준이다.
ORM(Object-Relational Mapping)은 객체와 관계형 데이터베이스를 매핑한다는 뜻
jpa.persist(member); // 저장
Member member = jpa.find(memberId); // 조회
Album album = jpa.find(Album.class, albumId);
SELECT I.*, A.*
FROM ITEM I
JOIN ALBUM A ON I.ITEM_ID = A.ITEM_ID
(내 생각들)
내부 동작 방식
영속 상태 : JPA가 관리하는 상태
영속성 컨텍스트의 변경내용을데이터베이스에 반영
💡 매핑한 엔티티를 엔티티 매니저를 통해 어떻게 사용할까?
⭐ 엔티티 매니저는 엔티티를 저장, 수정, 삭제, 조회하는 등 엔티티와 관련된 모든 일을 처리함.
➡️ 이름 그대로 엔티티를 관리하는 관리자
private final EntityManager em;
public void save(Member member) {
em.persist(member);
}
public Member findOne(Long id) {
return em.find(Member.class, id);
}
💡 개발자 입장에서 엔티티 매니저란?
→ 엔티티를 저장하는 가상의 데이터베이스로 생각하면 됨
※ 참고
엔티티 매니저 팩토리 : 엔티티 매니저를 만드는 공장 (비용 ↑)
영속성 컨텍스트(persistence context) : 엔티티를 영구 저장하는 환경
→ 엔티티 매니저로 엔티티를 저장하거나 조회하면, 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리한다.
em.persist(member);
※ 참고
회원 엔티티를 저장한다는 것은,
persist() 메소드는 엔티티 매니저를 사용해서 회원 엔티티를 영속성 컨텍스트에 저장한다.
🚨 영속성 컨텍스트를 직접 본 적은 없을 것임.
∵ 논리적인 개념에 가깝고, 눈에 보이지도 않음.
영속성 컨텍스트는 엔티티 매니저를 생성할 때 하나 만들어진다.
또한 엔티티 매니저를 통해 영속성 컨텍스트에 접근할 수 있고, 영속성 컨텍스트를 관리할 수 있음.
//객체를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
영속 상태 : 영속성 컨텍스트에 의해 관리된다.
※ em.find()나 JPQL을 사용해서 조회한 엔티티도 영속성 컨텍스트가 관리하는 영속 상태이다.
//객체를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername(“회원1”);
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
//객체를 저장한 상태(영속)
em.persist(member);
영속성 컨텍스트가 관리하던 영속 상태의 엔티티를 영속성 컨텍스트가 관리하지 않는 상태
//회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태
em.detach(member);
호출또는
엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제
//객체를 삭제한 상태(삭제)
em.remove(member);
💡 영속성 컨텍스트에 엔티티를 저장하면, 이 엔티티는 언제 데이터베이스에 저장될까?
→ JPA는 보통 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 데이터베이스에 반영한다.
→ 이것을 플러시(flush)라 한다.
영속성 컨텍스트이 변경 내용을 데이터베이스에 동기화하는 작업
∴ 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화한 후,
실제 데이터베이스 트랜잭션을 커밋함.
1. em.flush()를 직접 호출
영속성 컨텍스트를 강제로 플러시
2. 트랜잭션 커밋 시 플러시 자동 호출
데이터베이스에 변경 내용을 SQL로 전달하지 않고, 트랜잭션만 커밋하면 어떤 데이터도 DB에 반영 X.
∴트랜잭션을 커밋하기 전, 꼭 플러시를 호출해 영속성 컨텍스트의 변경 내용을 DB에 반영해야 함.
→ JPA는 이런 문제를 예방하기 위해 트랜잭션을 커밋할 때 플러시를 자동 호출함.
3. JPQL 쿼리 실행 시 플러시 자동 호출
JPQL이나 Criteria 같은 객체지향 쿼리를 호출할 때도 플러시가 실행됨.
※ 식별자 기준으로 조회하는 find()는 메소드를 호출할 때는 플러시 실행 X