자바 ORM 표준 JPA 프로그래밍_1

네코·2022년 7월 27일
0

김영한_JPA_기본

목록 보기
1/2

JPA란

프로그램을 작성 시 로직은 객체 지향적으로 작성할 수 있으나 결국 데이터 관리에선 DB는 sql만을 이해함으로 sql 작성이 필수적이다.
이러한 sql의 작성의 단점은

  • 반복되는 sql작성
  • sql에 의존적인 개발을 피하기 어렵다.

객체, 관계형DB 차이

객체 : 상속 O, 연관관계 O(참조),
관계형DB(이하RDB) : 상속 X, 연관관계 O(PK,FK)

객체에서 상속 관계의 (item, album)이 있다고 가정하자
이를 RDB에 저장하려고 하면 item과 album 각각에 맞는 insert 쿼리를 두번 사용하게된다.

만약 이와 달리 java collection을 활용하여 list에 album을 저장하려고 한다면,
list.add(album), list.get(albumId) 등과 같이 간단하게 작업을 할 수 있다.

객체와 RDB 모두 연관관계를 표현할 수 있다.
객체의 관점에서 연관관계는 참조하는 쪽에서만 값을 읽어올 수 있고
참조 당하는 쪽에서는 참조 하는 쪽을 알 수 없다.

그러나 RDB에서는 referenced key와 referencing key를 통해 양쪽에서 서로를 참조할 수 있게 된다.

JPA 구동 방식

  1. Persistence라는 클래스 (?)에서 설정 정보를 조회한다(maven 기준 META-INF의 .xml파일)
  2. Persistence가 EntityManagerFactory를 생성한다
  3. EntityManagerFactory에서 필요에 따라 entityManager를 생성한다.

Jpa는 transaction 단위로 관리된다.
entityManager에서 transaction을 얻어 start()하고 작업을 마친 후 commit()한다.

update

동일 트랜잭션에서 entityManager.find()를 통해 얻은 entity의 값을 바꾸기만 해도 따로 entityManager.persist() 호출 없이 DB에 수정된 값이 저장된 것을 확인할 수 있었다.

영속성 관리

영속성 컨텍스트

jpa의 큰 축 2가지

  • 객체와 RDB 매핑 설계
  • 영속성 컨텍스트

번역하면 "엔티티를 영구 저장하는 환경"을 의미한다.
EntityManager.persist(entity)는 DB에 저장하는 것이 아닌 엔티티 매니저를 통해 entity를
영속성 컨텍스트에 저장하는 것이다. 엔티티를 영속화한다(접근한다)

엔티티 매니저를 생성하면 그 안에 영속성 컨텍스트가 1개 생성된다. (1:1)

엔티티의 생명주기

비영속

jpa와 관계없이 java 객체가 생성된 상태이다.
ex) Member member = new Member();

영속

ex) em.persist(member) 시 영속성 컨텍스트에서 member가 관리된다.
영속성 컨텍스트에 저장된다고 DB에 해당 작업의 쿼리가 바로 실행되는 것이 아닌 해당 트랜잭션이
commit 되는 시점에 쿼리가 실행된다.

준영속,remove

영속성 컨텍스트에서 해당 객체를 지운다.
ex) em.detach(member), em.remove(member)

이점

DB 와 App 사이에 새로운 계층이 있는 것과 같다.

1차 캐싱

영속성 컨텍스트 내부에 1차 캐시가 있다.
key:value맵으로 key는 pk값, value는 엔티티 객체가 된다.
따라서 조회 시 (ex em.find()) 우선적으로 해당 영속성 컨텍스트를 살펴 존재할 경우 캐시의 해당 value를 가져온다.
=> 한 트랜잭션에서만 해당하는 것으로 성능에 큰 이점은 없다.

영속 엔티티의 동일성 보장

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

영속성 컨텍스트 안에 쓰기 지연 SQL 저장소가 존재
새 엔티티를 persist()한 경우 1차 캐시에 저장하고 해당 엔티티에 알맞은 insert sql을 생성하여 쓰기 지연 SQL 저장소에 저장한다.
이후 commit 시점에 flush된다.

변경감지

commit 호출 시 내부적으로 flush() 메서드가 실행된다. 실행되면 1차 캐시에서 entity 값과 스냅샷을 비교한다.
스냅샷은 엔티티 객체가 최초(?) 영속화될 때의 값을 떠둔 것을 의미하고, flush() 시점의 value와 스냅샷을 비교해 다르면 update 쿼리를 저장소에 생성하고 실행하게 된다.

플러시란?
영속성 컨텍스트의 변경 내용을 DB에 반영하는 것이다.
em.flush()와 같이 호출할 수 있다.
플러시하여도 query가 실행되어 DB를 업데이트 하는 것이지 1차 캐시의 값들이 사라지지 않는다.

jpql 쿼리 실행 시 플러시가 자동으로 호출된다.

준영속

em.detach()
em.clear()
em.close()

0개의 댓글