Notice
Recent Posts
Recent Comments
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

충분히 쌓여가는

엔티티 매니저, 영속성 컨텍스트 본문

Spring/Spring Boot

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

빌드이너프 2023. 12. 21. 14:09

엔티티 entity

데이터베이스의 테이블과 매핑되는 객체

엔티티는 본질적으로 자바 객체이므로 일반 객체와 다르지 않지만,

데이터베이스의 테이블과 직접 연결된다는 특별한 특징이 있어 구분지어 부른다

엔티티는 객체이긴 하지만 데이터베이스에 영향을 미치는 쿼리를 실행하는 객체

 

엔티티 매너저 entity manager

엔티티를 관리해 데이터베이스와 애플리케이션 사이에서 객체를 생성, 수정, 삭제하는 등의 역할

엔티티 매니저를 만드는 곳이 엔티티 매니저 팩토리(entity manager factory)

스프링 부트에서는 엔티티 매니저 팩토리를 하나만 생성하여 관리한다

@PersistenceContext 또는 @Autowired 애너테이션을 사용하여 엔티티 매니저를 사용

@PersistenceContext
EntityManager em; // 프록시 엔티티 매니저, 필요할 때 진짜 엔티티 매니저 호출

 

스프링 부트는 기본적으로 빈을 하나만 생성해서 공유하므로 동시성 문제가 발생할 수 있다

따라서 엔티티 매니저가 아닌 실제 엔티티 매너저와 연결하는 프록시(가짜) 엔티티 매너지를 사용

필요할 때 데이터베이스 트랜잭션과 관련된 실제 엔티티 매니저를 호출


 

영속성 컨텍스트

엔티티 매니저는 엔티티를 영속성 컨텍스트에 저장하는 특성이 있다

영속성 컨텍스트는 JPA의 중요한 특징 중 하나로, 엔티티를 관리하는 가상의 공간

영속성 컨텍스트가 있기 때문에 데이터베이스에서 효과적으로 데이터를 가져올 수 있고, 엔티티를 편하게 사용할 수 있다

특징으로 1차 캐시, 쓰기 지연, 변경 감지, 지연 로딩 => 모두 데이터베이스의 접근을 최소화해 성능을 높일 수 있다

 

1차 캐시

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

캐시의 key는 엔티티의 @Id 애너테이션이 달린 기본키 역할을 하는 식별자이며 값은 엔티티이다

엔티티를 조회하면 1차 캐시에서 데이터를 조회하고 값이 있으면 반환한다

값이 없으면 데이터베이스에서 조회해 1차 캐시에 저장한 다음 반환한다

=> 캐시된 데이터를 조회할 때에는 데이터베이스를 거치지 않아도되므로 매우 빠르게 데이터를 조회할 수 있다

 

쓰기 지연 transactional write-behind

트랜잭션을 커밋하기 전까지는 데이터베이스에 실제로 질의문을 보내지 않고 쿼리를 모았다가 트랜잭션을 커밋하면 모았던 쿼리를 한번에 실행하는 것

데이터 추가 쿼리가 3개라면 영속성 컨텍스트는 트랜잭션을 커밋하는 시점에 3개의 쿼리를 한꺼번에 쿼리를 전송

=> 적당한 묶음으로 쿼리를 요청할 수 있어 데이터베이스 시스템의 부담을 줄일 수 있다

 

변경 감지

트랜잭션을 커밋하면 1차 캐시에 저장되어 있는 엔티티의 값과 현재 엔티티의 값을 비교해서 변경된 값이 있다면 변경 사항을 감지해 변경된 값을 데이터베이스에 자동으로 반영

쓰지 지연과 마친가지로 적당한 묶음으로 쿼리를 요청할 수 있고, 데이터베이스 시스템의 부담을 줄일 수 있다

 

지연 로딩 lazy loding

쿼리로 요청한 데이터를 애플리케이션에 바로 로딩하는 것이 아니라 필요할 때 쿼리를 날려 데이터를 조회하는 것

 

즉시 로딩

조회할 때 쿼리를 보내 연관된 데이터를 가져옴


 

엔티티의 상태

엔티티는 4가지 상태를 가지고, 필요에 따라 엔티티 상태를 조절해 데이터를 올바르게 유지하고 관리할 수 있다

분리(detached) 상태: 영속성 컨텍스트가 관리하고 있지 않은 상태

관리(managed) 상태: 영속성 컨텍스트가 관리하는 상태

비영속(transient) 상태: 영속성 컨텍스트와 관계가 없는 상태

삭제된(removed) 상태

public class EntitiyManagerTest {
    @Autowired
    EntityManager em;
    
    public void example() {
    	// 엔티티 매니저가 엔티티를 관리하지 않는 상태(비영속 상태)
        Member member = new Member(1L, "홍길동");
        
        // 엔티티가 관리되는 상태
        em.persist(member);
        
        // 엔티티 객체가 분리된 상태
        em.detach(member);
        
        // 엔티티 객체가 삭제된 상태
        em.remove(member);
    }
}

'Spring > Spring Boot' 카테고리의 다른 글

@Entity, @NoArgsConstructor, @Id, @GeneratedValue  (0) 2023.12.21
스프링 데이터 JPA  (0) 2023.12.21
ORM, JPA, hibernate  (0) 2023.12.21
테스트 코드  (0) 2023.12.20
H2 데이터베이스와 lombok을 build.gradle에 추가  (0) 2023.12.19