🏆 2024

맛집 분야 크리에이터

🏆 2023

IT 분야 크리에이터

👩‍❤️‍👨 구독자 수

182

✒️ 게시글 수

0
https://tistory1.daumcdn.net/tistory/4631271/skin/images/blank.png 네이버블로그

🩷 방문자 추이

오늘

어제

전체

🏆 인기글 순위

티스토리 뷰

728x90
반응형

 

 

 

스프링 부트 쇼핑몰 프로젝트 with JPA 라는 책을 읽으며 정리한 내용입니다, 
이미 스프링부트로는 개발을 많이 해보았으나 JPA를 공부하기 위해 이 책을 골랐습니다.

 

 

 

 

이전 포스트를 보려면 아래 링크를 클릭하세요.

[SpringBoot + JPA] tutorial: 스프링 부트 쇼핑몰 프로젝트 with JPA -1. 애플리케이션 생성 및 설정하기

[SpringBoot + JPA] tutorial: 스프링 부트 쇼핑몰 프로젝트 with JPA -2. Controller, DTO(lombok)

 

 

 

 

JPA (java Persistence API)는 자바 ORM 기술에 대한 API 표준입니다.
ORM이란 Object Relational Mapping의 약자로 객체와 관계형 DB를 매핑해주는 것을 말합니다.
즉, JPA는 인터페이스이고, 이를 구현한 대표적인 구현체로 Hibernate, EclipseLink, DataNucleus, OpenJpa, TopLink 등이 있습니다.
JPA 인터페이스를 구현한 가장 대표적인 오픈소스가 Hibernate(하이버네이트)입니다. 실질적인 기능은 하이버네이트에 구현되어 있는 것입니다.

- JPA 사용 시 장점
1. 특정 DB에 종속되지 않음 : 설정파일에 어떤 DB를 사용하는지 수정만하면 얼마든지 DB를 변경할 수 있습니다.
2. 객체지향적 프로그래밍 : JPA를 사용하면 데이터베이스 설계 중심의 패러다임에서 객체지향적으로 설계가 가능합니다.
3. 생산성 향상 : DB 테이블에 새 컬럼이 생성될 경우, DTO에도 추가하는 등의 변경이 필요하나, JPA에서는 테이블과 매핑된 클래스에 필드만 추가한다면 쉽게 관리가 가능합니다. 또한 SQL문을 직접 작성하지않고 객체 사용이 가능하여 유지보수 측면에서도 좋고 재사용성도 증가합니다.

- JPA 사용 시 단점
1. 복잡한 쿼리 처리 : 통계처리 같은 복잡한 쿼리를 사용할 경우 SQL문을 사용하는 것이 나을수도 있습니다. SQL과 유사한 기술인 JPQL을 지원합니다. 
2. 성능저하 위험 : 객체 간 매핑 설계를 잘못했을 때 성능저하가 일어날 수 있으며, 자동으로 생성되는 쿼리가 많기 떄문에 의도치 않은 쿼리로 성능이 저하되기도 합니다. (외래키로 엮여있다면 join을 계속 하기 때문에)
3. 학습시간: JPA는 제대로 사용하려면 알아야할 것이 많아서 학습하는데 시간이 오래 걸립니다.


 

이미지출처: https://developer-pi.tistory.com/307

 

[Spring] JPA 동작 방식

엔티티란 데이터베이스의 테이블에 대응하는 클래스라고 생각하시면 됩니다. @Entity가 붙은 클래스는 JPA에서 관리하며 엔티티라고 합니다. 데이터베이스에 item 테이블을 만들고, 이에 대응되 는

developer-pi.tistory.com

 

 

 

반응형

 

 

엔티티(Entity)란 데이터베이스의 테이블에 대응하는 클래스라고 생각하시면 됩니다.
@Entity가 붙은 클래스는 JPA에서 관리합니다.

데이터베이스에 item 테이블을 만들고, 이에 대응되는 item.java 클래스를 만들어서 @Entity 어노테이션을 붙이면 이 클래스가 엔티티가 되는 것입니다. 클래스 자체나 생성한 인스턴스도 엔티티라고 부릅니다. 

엔티티 매니저 팩토리(Entity Manager Factory)란?
: 엔티티 매니저 인스턴스를 관리하는 주체입니다. 애플리케이션 실행 시 한 개만 만들어지며, 사용자로부터 요청이 오면 엔티티 매니저 팩토리로부터 엔티티 매니저를 생성합니다.

엔티티 매니저(Entity Manager)란?
: 영속성 컨텍스트(Persistance Context)에 접근하여 엔티티에 대한 DB작업을 제공합니다. DB커넥션을 사용하여 DB에 접근합니다.
엔티티 매니저의 몇 가지 메소드를 살펴봅시다.

 

1. find() : 영속성 컨텍스트에서 엔티티를 검색하고, 없을 경우 DB에서 데이터를 찾아 영속성 컨텍스트에 저장합니다.
2. persist() : 엔티티를 영속성 컨텍스트에 저장합니다.
3. remove() : 엔티티클래스를 영속성 컨텍스트에서 삭제합니다.
4. flush() : 영속성 컨텍스트에 저장된 내용을 데이터베이스에 반영합니다.

 

 

 

영속성 컨텍스트(Persistance Context)란?
: 엔티티를 영구 저장하는 환경으로 엔티티 매니저를 통해 영속성 컨텍스트에 접근합니다.

영속성 컨텍스트는 애플리케이션과 데이터베이스의 사이에있는 중간 계층으로, 버퍼링, 캐싱 등을 할 수 있는 장점이 있습니다.

 

영속성 컨텍스트에는 1차 캐시라는 것이 존재하며, Map(KEY, VALUE)로 저장됩니다.

entityManager.find() 메소드 호출 시 영속성 컨텍스트의 1차 캐시를 조회합니다.

영속성 컨텍스트의 1차 캐시 구조는 아래와 같습니다.

이미지 출처:https://keencho.github.io/posts/JPA-cache/ - JPA 캐시

 

item을 영속성 컨텍스트에 조회하고, item이 영속성 컨텍스트의 1차캐시에 저장되어 있지 않으면 DB를 조회합니다.

조회한 item 엔티티는 1차 캐시에 저장되고, item 엔티티 결과값을 반환하게 됩니다.

1차 캐시에 저장된 엔티티를 조회하기 때문에, 하나의 트랜잭션에서 같은 키값으로 영속성 컨텍스트에 저장된 엔티티 조회 시 같은 엔티티 조회를 보장합니다. (동일성 보장)

 

 

728x90

 

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

영속성 컨텍스트에는 쓰기 지연 SQL 저장소가 존재합니다.

entityManager.persist()를 호출하면 1차 캐시에 저장되는 것과 동시에 쓰기 지연 SQL 저장소에 SQL문이 저장됩니다.

이렇게 SQL을 쌓아두고 트랜잭션을 커밋하는 시점에 저장된 SQL문들이 flush되면서 DB에 반영됩니다.

이렇게 모아서 보내기 때문에 성능에서 이점을 볼 수 있습니다.

이미지출처:https://velog.io/@dlehddud60/1%EC%B0%A8-%EC%BA%90%EC%8B%9C%EC%99%80-%EB%8F%99%EC%9D%BC%EC%84%B1-%EB%B3%B4%EC%9E%A5 - 1차 캐시와 동일성 보장 쓰기지연 변경감지

 

 

 

 

변경 감지

JPA는 1차 캐시에 데이터베이스에서 처음 불러온 엔티티의 스냅샷 값 (데이터베이스에서 엔티티를 처음 로드했을 때의 상태값)을 갖고 있습니다.

그리고 1차 캐시에 저장된 엔티티와 스냅샷을 비교 후 변경 내용이 있다면 UPDATE SQL문을 쓰기 지연 SQL 저장소에 담아두고,

커밋시점에 변경 내용을 자동으로 반영합니다. 즉, 따로 update문을 호출할 필요가 없습니다.

 

 

 

엔티티 생명주기

 

이미지 출처: https://devkingdom.tistory.com/271 - [JPA] Entity의 4가지 상태

 

 

엔티티 생명주기를 상세하게 살펴보면 다음과 같습니다.

엔티티 생명주기 내용
비영속(new) new 키워드를 통해 생성된 상태로 영속성 컨텍스트와는 관련이 없는 상태
영속(managed) 엔티티가 영속성 컨텍스트에 저장된 상태로 영속성 컨텍스트에 의해 관리되는 상태. 
영속 상태에서 데이터베이스에 저장되지 않으며, 트랜잭션 커밋 시점에 데이터베이스에 반영
준영속 상태(detached) 영속성 컨텍스트에 엔티티가 저장되었다가 분리된 상태
삭제 상태(removed) 영속성 컨텍스트와 데이터베이스에서 삭제된 상태

 

 

 

상품 엔티티를 만들어서 영속성 컨텍스트에 저장한 후 데이터베이스에 반영하는 코드를 살펴보겠습니다.

 

 

 

        // 비영속 상태 (new / transient)
        // 영속성 컨텍스트에 저장할 상품 엔티티를 생성합니다.
        // new 키워드를 통해 생성했으므로 영속성 컨텍스트와 관련이 없는 상태입니다.
        Item item = new Item();
        item.setItemNm("상품명");
        
        // 엔티티 매니저 팩토리로부터 엔티티 매니저를 생성합니다. 
        EntityManager em = entityManagerFactory.createEntityManager();

        // 엔티티매니저는 데이터 변경 시 데이터무결성을 위해 반드시 트랜잭션을 시작해야 합니다. 
        // 여기서의 트랜잭션도 DB의 트랜잭션과 같은 의미로 생각하면 됩니다.
        EntityTransaction transaction = em.getTransaction();
        transaction.begin();

        // 영속 상태 (managed)
        // 생성한 상품 엔티티가 영속성 컨텍스트에 저장된 상태입니다. 여기까지는 DB에 insert sql을 보내지 않은 단계입니다.
        em.persist(item);

        // 트랜잭션을 DB에 반영합니다. 이때 영속성 컨텍스트에 저장된 상품 정보가 DB에 insert되면서 반영됩니다.
        transaction.commit();

        // 엔티티 매니저와 엔티티 매니저 팩토리의 close() 메소드를 호출해 사용한 자원을 반환합니다.
        em.close();
        emf.close();

 

 

 

 

 

다음 포스팅을 읽으려면 아래링크를 눌러주세요.

[SpringBoot + JPA] tutorial: 스프링 부트 쇼핑몰 프로젝트 with JPA -4. Entity 설계하기

 

 

 

 

 

 

 

728x90
반응형
댓글