TIL을 잘 정리해서 쓰려고 하다보니 그 자체가 부담으로 다가오고 시간도 많이 잡아먹어서 꽤 긴 기간동안 쓰지않고 넘겨왔다.. 오늘부터 이쁘고 잘 쓰려고 하기보다 오늘 배운 내용 및 했던 활동들을 간단하게 남기는 느낌으로 매일매일 쓰기에 도전해 보겠다!!
오늘은 JPA에서 객체를 뜻하는 Entity에 대한 강의를 들었다. Entity들은 데이터베이스의 테이블과 매핑되어 관리된다. Entity를 관리하는 공간, 방법 등에 대해서 알아보겠다.
영속성 컨텍스트란 이 Entity객체들을 효율적으로 관리하기 위해서 만들어진 공간이다. 복잡한 쿼리문을 배워서 작성할 필요 없이 JPA를 사용하여 데이터에 접근할 수 있게 해준다.
다음은 영속성 컨텍스트의 기능들이다.
영속성 컨텍스트는 내부적으로 Map형식의 캐시 저장소를 가지고 있다. 여기서 Id는 PK(식별자 값) 을 저장한다. 이러한 캐시 저장소를 활용하는 방법을 알아보자.
em.persist(memo); 메서드가 호출되면 memo Entity 객체를 캐시 저장소에 저장한다.
em.find(Memo.class,1);메서드로는 조회를 할 수 있는데 캐시에 해당 값이 없다면 DB로 접근하여 조회 후 해당 값을 캐시 저장소에 저장하고 반환해준다! 즉 DB에만 있고 캐시에는 저장되지 않은 데이터도 조회할 수 있다. 또한 데이터가 변경되지 않기 때문에 트랜잭션 없이도 조회는 가능하다.
또한 1차 캐시는 객체 동일성 보장을 해준다. DB row 1개당 객체 1개가 사용되는 것을 보장한다.
JPA는 트랜잭션 처럼 SQL을 모아서 한번에 DB에 반영한다. JPA에서는 이를 위해서 쓰기 지연 저장소를 만들어서 SQL을 모아두었다가 트랜잭션 commit을 실행하면 한번에 DB에 반영한다. 이때 데이터가 변경된다면 트랜잭션이 필요하다.
데이터가 변경될 때마다 쓰기 지연 저장소에 저장된다면 여러번 쿼리문을 호출하기 때문에 비효율적이다. JPA는 영속성 컨텍스트에 Entity를 저장할 때 최초 상태를 저장한다. 이 상황에서 트랜잭션이 commit되고 em.flush();가 호출되면 현재 상태와 최초 상태를 비교하여 변경 내용이 있다면 쓰기 지연 저장소에 저장하고 모든 쓰기 지연 저장소의 SQL을 DB에 요청한다.
따라서 변경하고 싶은 데이터를 먼저 조회하고 해당 Entity객체의 데이터를 변경하면 자동으로 Update SQL이 생성 및 반영된다. 예를들어 set등으로 직접 변경한 상태라면 커밋만 해도 자동으로 변경된다.