자바 ORM 표준 JPA 프로그래밍 - 기본편-2

존스노우·2021년 12월 30일
0

JPA

목록 보기
2/10

영속성 컨텍스트

JPA에서 가장 중요한 2가지

객체와 관계형 데이터베이스 매핑하기

영속성 컨텍스트 - JPA가 내부에서 어떻게 동작할까 ?

웹어플리케이션에서.
팩토리에서 고객의 요청할때마다 엔티티 매니저 생성
엔티티매니저는 내부적으로 데이터베이스 커넥션을 사용해서 디비를 사용하게 됨.

영속성 컨텍스트란?

JPA를 이해하는 가장 중요한 용어
엔티티를 영구 저장하는 환경 이라는 뜻
EntityManage.persist(entity) // 원래는 저장하는걸로 알고 있음

사실 엔티티를 영속성 컨텍스트라는 곳에 저장하는 것이다

엔티티 매니저? 영속성 컨텍스트?

영속성 컨텍스는 눈에 보이지않는 논리적인 개념

엔티티 매니저를 통해서 영속성 컨텍스트에 접근한다.

엔티티의 생명주기

비영속(new/transient)

영속성 컨텍스트와 전혀 관계없는 새로운상태 ex) new Member()

영속(managed)

ex)persist(entity)

준영속

삭제

비영속

영속

엔티티매니저 안에 영속성 컨텍스트 안에서 멤버가 관리된다.

이때는 DB에 저장되지 않음.

영속상태가 된다고 디비에 쿼리가 바로 날라가는 것이아님.

트랜잭션 커밋하는 순간 영속성 안에 있는 것들이 디비에 쿼리가 날라간다.

준영속 / 삭제

ex) em.detach(member); em.remove(member);

결론 : 애플리케이션과 데이터베이스 사이에 중간 계층이 있다

영속성 컨텍스트의 이점

1차 캐시

동일성 보장

트랜잭션이 지원하는 쓰기 지연

변경 감지

지연 로딩

엔티티 조회 , 1차 캐시

영속성 컨텍스트는 내부의 1차캐시를 가지고 있다.

비영속 - > 영속 상태가 되면 (앞에 필기한 것처럼)
( 지금은 엔티티매니저가 영속성 컨텍스트라 칭하자 약간 다르지만)

내부에는 1차 캐시가 있다. 1차캐시를 영속성 컨텍스트라 이해도 됨.

id와 멤버 객체 자체가 값

디비에서 조회가 아니라 1차 캐시에서 우선 조회

1차 캐시에 없을때?

DB에서 조회함 -> 1차 캐시에 저장

엔티티 매니저는 데이터 트랜잭션 단위로 만들고 종료함
고객요청 들어오고 끝나면 영속성 컨텍스트 종료 (찰 나의 순간)
한명 한명 고객의 요청이기때문에 성능 이점은 딱히 없다.(빠르게 끝나니깐)

여기선 셋팅을 안한 상태이기때문에 영속성컨텍스트 캐시가 비어있다

첫번째 줄에서 디비에서 조회해서 셀렉트문이 나가고 1차캐시에 저장되고 멤버를 반환하고
두번째 줄에선 캐시에 있는 객체를 가져와서 셀렉트를 날리지 않아도 된다.

비즈니스로직 복잡할때 같은걸 조회할땐 좀 단순해진다.

컨셉이 주는 이점은 객체지향적으로 코드 작성이 가능하다.

영속 엔티티의 동일성 보장

자바 컬렉션에서 == 비교하면 같은 경우 처럼.

위에 코드는 findMember1 == findMember2 같음

무슨말이냐 JPA가 영속 엔티티를 보장해준다.

가능한 이유는 1차캐시가 있기 때문

엔티티 등록 트랜잭션을 지원하는 쓰기 지연

인서트문을 보내기전에 쌓아두고 한번에...

memberA를 저장하면?

영속성 컨텍스트는 쓰기지연 SQL 저장소가 있다

memberA 1차캐시저장 -> memberA분석 insert Query 생성
-> 쓰기 지연 SQL 저장소에 저장

굳이? 쿼리가 바로바로 나가면 되지않나..

-> 버퍼링 기능을 쓸 수 있다.

배치 사이즈만큼 쌓아서 데이터베이스에 네트워크를 통해 한방에 쏠 수 있다.

버퍼링 기능 : 모았다가 한방에

크게 얻을 이점은 많지 않지만.
JPA를 쓰면 옵션 하나로 기본적으로 성능 하나를 먹고 들어 갈 수 있다.

엔티티 수정 변경감지

더티체킹이라고해서 엔티티 변경감지를 할 수 있다.

커밋 ->

엔티티 와 스냅샷 비교

스냅샷 : 값을 최초로 읽어온 시점

엔티티 삭제

em.remove(memberA) ;; //엔티티 삭제

그냥 딜리트가 나감.

플러시

영속성 컨텍스트의 변경내용을 데이터베이스에 반영

플러시 발생

변경 감지 (더티체킹)

수정된 엔티티 쓰기 지연 SQL 저장소에 등록

쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송(등록 수정 삭제 쿼리)

트랜잭션이 커밋이 되는게 아님.

영속성 컨텍스트 플 플러시 방법

em.flush() - 직접 호출 / 트랜잭션 커밋/ JPQL 쿼리 실행 나머지 두개는 자동 호출

플러시를 해도 1차캐시는 계속 있음

memberA,B,C 조회가 안됌.
그러면 문제가 생기니
JPQL은 자동으로 플러시가 되서 이런걸 미연의 방지

플러시는!

영속성 컨테스트를 비우지 않고 변경내용을 데이터베이스에 동기화.

트랜잭션이라는 작업 단위가 중요하기 때문에 / 커밋 직전에만 동기화 하면되기 때문

준영속 상태

em.find() 1차캐시에 없을 때? DB에서 가져온다.

1차캐시에 올라간 생태가 영속성 상태

영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached)

-> 영속성 컨텍스트가 제공하는 기능을 사용하지 못함

em.detach(entity) / em.clear() / em.close()

update 쿼리가 안나간다.

정리

객체와 관계형 데이터베이스 매핑하기 / 영속성 컨텍스트

영속성 컨텍스트 : 엔티티 영구적으로 저장하는 환경

논리적인 개념으로 눈에 보이지 않음 엔티티 매니저 안에 영속성 컨텍스트가 있음

비영속 / 영속 / 준영속 / 삭제 생명 주기가 있음

이점

1차 캐시

동일성 보장

트랜잭션을 지원하는 쓰기지연 : 버퍼링

변경 감지 : 업데이트

지연 로딩 : 나중에 뒤에 시간에

member.getTeam() 쿼리를 나중에 날림 .

profile
어제의 나보다 한걸음 더

0개의 댓글