[TIL] 2024-08-21

성장일기·2024년 8월 24일

회고

목록 보기
34/37

중요 학습 내용 [JPA]

JPA 사용 이유

Dialect를 통한 다양한 DBMS 연동 가능

  • 모든 DBMS 및 모든 DML, DQL이 가능한 것은 아니지만, 대부분의 쿼리 작성 가능

JDBC를 통한 direct SQL 문제점

  1. 개발시간 증가, 유지보수 저하

    • 데이터 변환
      • JDBC API 코드 등을 중복 작성
  2. SQL에 의존하여 개발

    • SQL 작성
      • difficult for handling syntax error
      • Tight Coupling for SQL(강결합)(String in Java)
  3. 패러다임 불일치

    • 상속

      • DB에서 상속은 Super/Sub type인데, Super type은 sub type의 속성을 공유하지 못해 다른 테이블로 분리

      • 객체지향 상속은 super type의 속성을 공유하기에 패러다임 불일치 발생

        • 데이터베이스 테이블에 맞춘 객체 모델

          public class Menu {
          private int menuCode;
          private String menuName;
          private int menuPrice;
          private int categoryCode; // hot spot
          private String orderableStatus;
        • 객체 지향 언어에 맞춘 객체 모델(JPA)

          public class Menu {
          private int menuCode;
          private String menuName;
          private int menuPrice;
          private Category categoryCode; // hot spot
          private String orderableStatus;
    • 연관관계

      • 객체지향에서 가지는(ASSOCIATION or COLLECTION) 연관관계 경우 데이터베이스 저장 구조와 다른 형태
    • 객체 그래프 탐색

    • 방향성

  4. 동일성 보장 문제

    • JDBC를 통한 객체 추출 시, 동일한 엔티티라도 다른 객체로 인식
    • JPA에서는 persist context에서 동일한 엔티티에 대해서 pk를 통해 객체를 가져오기에, 동일성 보장
      • 비영속 상태의 객체와 영속 상태의 객체는 동일보장 X

PROS

  • 객체지향 패러다임 중심의 개발이 가능
    • 객체지향(JAVA)과 관계지향(DB)의 서로 다른 패러다임 불일치를 해소
  • 생산성이 향상
    • Dialect를 통해 SQL문 자동 작성
  • 유지보수가 향상
    • SQL문을 자동 작성하여 SQL을 수정할 필요가 없기에 설정 및 필드 변경시 SQL이 자동 수정
  • DB의 종류에 맞는 SQL 작성
    • 개발자 대신 이를 판단하고 해당 DB에 맞는 SQL을 작성
  • 트랜잭션을 처리하는 시간 단축
    • 1차 캐시를 활용한 성능 최적화

CONS

  • 복잡한 쿼리에 적합하지 않음
  • JPA에 대한 기반 지식이 없으면 성능저하 발생 가능성이 높음
    • 자동 쿼리 수정이 가능하나, 수정 시, 모든 정보 수정
  • 객체지향 패러다임(JAVA)과 관계형 데이터베이스 패러다임에 대한 이해 필요
  • 복잡한 동적 SQL같은 경우 순수 JPA만으로는 부족
    • 추가 라이브러리 필요
      • QueryDSL
        • Q-Type을 다뤄야하기에 번거로움
      • JooQ etc..

JPA vs MyBatis

분류JPAMyBatis
역할ORMSQL Mapper
Difficulty복잡한 쿼리 처리 번거로움
DB 테이블이 변경되고 객체매핑이 변경되어야 함
직접 매핑,
수정 시, Mapper와 객체까지 모두 수정 필요
DB 스키마 변경시 쿼리만 변경하면 됨

JPA의 기본 동작방식

  • Java 애플리케이션과 JDBC사이에서 동작하며 내부적으로 JDBC API를 활용

Entity Life-cycle

  • JPQL, NativeQuery는 별도로 commit(flush)됨

  • 종류

    • 영속성 entity
      • persist()
        • EntityManager에게 persist(obj)로 객체 관리 요청
      • find()
        • EntityManager에게 find(obj)로 조회 요청(Entity Manager가 persistence context에서 관리 시작)
    • 준영속성 entity
      • 사용이유
        • JPA에서 엔티티를 더 이상 영속성 컨텍스트에서 관리하지 않음
        • 특정 상황에서 성능 최적화나 데이터 무결성 유지, 특정 작업 후 엔티티 변경 방지를 위해 사용
        • 관리되는 엔티티가 줄어들기에 성능최적화 가능
        • 트랜젝션이 오래 걸리는 경우, 관리해야할 영속성 컨텍스트에 존재하는 엔티티가 많으면 관리소요가 크다.
        • 엔티티 변경 방지: detached 된 엔티티와 DB에서 새로 조회해야하는 엔티티를 구분하기 좋다.
      • detach():
        • 해당 엔티티가 영속성 컨텍스트에서 잠시 배제됨
        • 이후 merge()로 영속성 컨텍스트에 다시 통합됨
      • clear():
        • 영속성 컨텍스트는 유지. persistence context 내 모든 영속성 엔티티는 준영속 상태
      • close():
        • 영속성 컨텍스트가 제거
        • 새로운 persistence context를 원하면 entity manager도 다시 생성 필요
        • 모든 영속성 엔티티는 준영속 상태가 됨
    • 비영속성 entity
      • 삭제 상태 entity
        • remove():
          • 해당 엔티티 영속성 컨텍스트에서 제거
  • use

    • SELECT
      • EntityManager에게 특정 entity 최초 find 요청
        • 1차 캐시에 있으면 반환
          • DB로 조회X(DB와 소통 횟수 감소)
        • 1차 캐시에 없으면 DB에 JPQL로 SELECT하여 1차 캐시에 영속성 Entity로 저장 후 반환
        • DB에도 없으면 null 반환
    • UPDATE
      • persist()를 통해 EntityManager에게 엔티티 관리 요청
        • DB에 해당 PK의 엔티티가 존재하는지 확인
        • 쓰기 지연 저장소에 해당하는 쿼리 저장
      • 해당 엔티티 변경
        • 변경에 맞는 쿼리 쓰기 지연 저장소에 해당하는 쿼리 저장
      • commit(transaction 종료 직전) 시, 최적화된 쿼리가 flush를 통해 DB와 동기화
      • 모든 칼럼에 대해 update하기에, 효율이 좋지 않다.

Persistence Context

  • Entity Manager Factory:

    • 엔티티 매니저를 생성할 수 있는 기능을 제공하는 클래스
    • thread-safe하기에 여러 스레드가 동시에 접근해도 안전함. 따라서 서로 다른 스레드 간 공유해서 재사용
    • thread-safe한 기능을 요청 스코프마다 생성하기에는 비용(시간, 메모리) 부담이 큼
      • application 스코프와 동일하게 싱글톤으로 생성해서 관리하는 것이 효율적
    • 따라서 데이터베이스를 사용하는 애플리케이션 당 한 개의 EntityManagerFactory를 생성
  • Entity Manager:

    • 엔티티를 저장하는 메모리 상의 데이터베이스를 관리하는 인스턴스
    • 엔티티를 저장하고, 수정, 삭제, 조회하는 등의 엔티티와 관련된 모든 일을 함
    • service layer에서 per transaction, per request로 생성됨
    • 엔티티 매니저는 thread-safe하지 않기에 동시성 문제가 발생 가능
      • 따라서 스레드 간 공유 X
      • web의 경우 일반적으로 request scope와 일치시킴
  • Persistence Context

    • 영속성 컨텍스트는 엔티티를 key-value 방식으로 저장하는 저장소
    • 영속성 컨텍스트는 엔티티 매니저를 생성할 때 동시에 생성된다(하나가 생성)
    • 엔티티 매니저를 통해 엔티티를 저장하고, 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리
    • 엔티티 매니저를 통해서 영속성 컨텍스트에 접근 및 관리 가능

1차 캐시

@IdEntitySnapShot
m1menu1(pk)menu1
Snapshot
m2menu2(pk)menu2
Snapshot
.........
profile
엔지니어로의 성장일지

0개의 댓글