처음부터 엔티티 매핑 섹션까지 정리
JPA는 특정 데이터베이스에 종속되지 않는다.
![](https://velog.velcdn.com/images/eunsiver/post/d872aeb1-5c3b-4f28-977d-bd2789c5cfdb/image.png)
JPA 구동 방식
- 설정 정보 조회
- EntityManagerFactory 생성
- EntityManager들을 생성
![](https://velog.velcdn.com/images/eunsiver/post/36db9eff-93b1-4559-a1f8-a7c05bb1bfed/image.png)
EntityManagerFactory emf=Persistence.createEntityManagerFactory("hello");
EntityManager em=emf.createEntityManager();
EntityTransaction tx=em.getTransaction();
tx.begin();
tx.commit();
em.close;
emf.close;
모드 데이터 변경은 Transaction 안에서 진행
![](https://velog.velcdn.com/images/eunsiver/post/024c37a0-9e65-4e2c-a091-f07ee596f62f/image.png)
![](https://velog.velcdn.com/images/eunsiver/post/f5f870be-9ec9-49a1-9f0d-2188e76b5a69/image.png)
- 엔티티 매니저 팩토리: 하나만 생성해서 애플리케이션 전체에서 공유
- 엔티티 매니저는 쓰레드간에 공유하지 않음. 사용하고 버리기
- 🧨🧨JPA의 모든 데이터 변경은 트랜잭션 안에서 실행
JPQL
- JPA를 사용하면 엔티티 객체를 중심으로 개발
- JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어 제공
- JPQL은 엔티티 객체를 대상으로 쿼리
- SQL은 데이터베이스 테이블을 대상으로 쿼리
JPA에서 가장 중요한 2가지🎈
- 객체와 관계형 데이터베이스 매핑하기(Object Relation Mapping)
- 영속성 컨텍스트
![](https://velog.velcdn.com/images/eunsiver/post/614fc506-c11d-4cdb-9651-1da940b49e4c/image.png)
영속성 컨텍스트
- JPA를 이해하는데 가장 중요한 용어
- 엔티티를 영구 저장하는 환경
- EntityManager.persist(entity)
- 엔티티 매니저를 통해서 영속성 컨텍스트에 접근
비영속 상태
![](https://velog.velcdn.com/images/eunsiver/post/92a2b1a4-5d4e-45dd-a036-04df3435237d/image.png)
영속 상태
![](https://velog.velcdn.com/images/eunsiver/post/4e1f8f78-019a-4772-8b0a-278aca4802b4/image.png)
Member member=new Member();
member.setId(100L);
member.setName("HelloJPA")
em.persist(member);
영속 상태가 된다고 DB에 쿼리가 바로 날라가는 것이 아니라
commit을 해야 DB에 저장이 된다.
영속성 컨텍스트의 이점
- 1차 캐시
- 동일성 보장
- 트랜잭션을 지원하는 쓰기 지연
- 변경 감지
- 지연 로딩
1차 캐시는 한 Transaction안에서의 효과가 있기 때문에 괸장히 찰나이며 큰 이득은 없다.
한번 조회한 후 또 조회하면 두번째 부터는 쿼리가 나가지 않고 캐시를 이용하여 조회한다.(한 트랜잭션 안에서)
![](https://velog.velcdn.com/images/eunsiver/post/f8b3aef9-1657-430b-a051-233f437382e0/image.png)
이 부분에서 처음에는 DB select 쿼리가 나가고 이 값은 캐시에 저장되므로
두번째 find에서는 select 쿼리가 나오기 않는다.
![](https://velog.velcdn.com/images/eunsiver/post/afe1b84a-617d-45ab-ac54-d554d0b858b4/image.png)
조회를 했는데 1차 캐시에 없으면 DB에서 조회하고 1차 캐시에 저장을 하고 반환을 해준다.
영속 엔티티의 동일성 보장 (같은 트랜젝션 안에서)
- ==비교에서 똑같은 것 처럼
- 자바 컬렉션에서 가져왔을때 주소가 같은 것처럼 == 비교로 동일성을 보장한다.
엔티티 등록할 때 트랜잭션을 지원하는 쓰기 지연
![](https://velog.velcdn.com/images/eunsiver/post/23e9338a-4401-4ec3-91d1-1d0ff5571d5f/image.png)
커밋 했을 때 DB로 insetSQL을 보냄.
![](https://velog.velcdn.com/images/eunsiver/post/1027e31a-80c3-4209-9db7-8af8da46b4b0/image.png)
![](https://velog.velcdn.com/images/eunsiver/post/e9bb79f6-7d08-491f-ad2e-5cd5a6d256a8/image.png)
엔티티 수정, 변경 감지(dirty checking)
- 변경 후에 persist하지 않아도 됨📌📌
- java Collection과 비슷한 개념
- em.update와 같은 코드가 없어도 됨
![](https://velog.velcdn.com/images/eunsiver/post/990ac29e-13ff-4cf7-93bf-535468e489e3/image.png)
플러시
- 영속성 컨텍스트의 변경내용을 데이터베이스에 반영
- 영속성 컨텍스트의 쿼리들을 DB에 날려줌
- commit 되면 플러시가 자동으로
- 변경 감지
- 수정된 엔티티를 쓰지 지연 SQL 저장소에 등록
- 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송(등록, 수정, 삭제 쿼리)
영속성 컨텍스트를 플러시하는 방법
- em.flush(): 직접/강제 호출(test 할때 유용), commit 전에 쿼리 나감.
플러시를 해도 영속성 컨텍스트 유지
- 트랜잭션 커밋: 플러시 자동 호출
- JPQL 쿼리 실행: 플러시 자동 호출
플러시 실행 옵션
- commit && 쿼리 날릴때 실행(기본값): FlushModeType.AUTO
- commit할 때만 플러시: FlushModeType.COMMIT
- AUTO로 손대지말고 쓰는 것을 권장
플러시는
- 영속성 컨텍스트를 비우지 않음
- 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화
- 트랜잭션이라는 작업 단위가 중요-> 커밋 직전에만 동기화
준영속 상태
- 영속 상태의 엔티티가 영속성 컨텍스트에서 분리
- 영속성 컨텍스트가 제공하는 기능(dirty checking) 사용 못함
- 준영속 상태로 만드는 법
em.detach()
Memeber member=em.find(Member.class,10L);
member.setName("aaa");
em.detach(member);
tx.commit();
이때 select쿼리는 나가고 update쿼리는 나가지 않음.
준영속 상태이기 때문에 변경감지 기능을 하지 않음
- 특정엔티티만 준영속 상태로 전환: em.detach()
- em.clear(): 영속성 컨텍스트 전체 초기화
- em.close(): 영속성 컨텍스트를 종료
@Entity
- @Entity가 붙은 class는 JPA가 관리
- 기본 생성자 필수(파라미터가 없는 public/protected 생성자)
- final, enum, interface, inner 클래스 사용 X
- 저장할 필드에 final 사용 X
데이터베이스 스키마 자동 생성
- DDL을 애플리케이션 실행 시점에 자동 생성
- 테이블 중심-> 객체 중심
- DDL은 개발 장비에서만 사용
- 생성된 DDL은 운영 서버에서 사용하지 않거나 적절히 다듬은 후 사용
create, create-drop, update, validate, none
- 운영 장비에서는 절대 create, create-drop, update를 사용하면 안됨
- 개발 초기 단계는
create/update
- 테스트 서버는
update/validate
- 스테이징과 운영 서버는
validate/none
DDL 생성 기능은 DDL을 자동 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않는다.
매핑 어노테이션
- @Column
- @Temporal: 날짜
- @Enumerated: enum
- @Lob: BLOB,CLOB
- @Transient: 특정 필드를 컬럼에 매핑하고 싶지 않을때
@Enumerated
주의!🎈 ORDINAL 사용 X, 💥STRING💥만을 사용하자
EnumType.STRING
: 이름을 데이터베이스에 저장