티스토리 뷰

웹 개발/SpringBoot

JPA에 대해서

빵파레2 2019. 11. 10. 20:52

JPA란?


  • Java Persistance API

  • 자바 진영의 ORM 표준

  • 인터페이스들의 모음 (즉, 그 자체로 실행될 수 있는 것은 아님)

  • JPA를 구현한 실질적인 구현체중 가장 많이 사용되는 것이 바로 Hibernate이다.

 

ORM이란?


  • Object-Relational Mapping (여기서 R은 관계형 DB의 R을 의미)

  • 객체는 객체대로 설계하고 관계형 DB는 관계형 DB대로 설계함, 여기서 ORM 프레임워크가 중간에서 서로를 매핑하는 역할을 수행함

 

JPA의 동작 과정


  • JPA는 애플리케이션과 JDBC 사이에서 동작함.

  • 개발자가 JPA를 사용하면, JPA 내부에서 JDBC API를 사용해 DB와 통신한다.

  • 즉, JPA가 JDBC와는 별개의 또다른 기술을 이용해 DB와 통신하는 것이 아니다. (JDBC를 통해 DB와 연결)

 

JPA를 사용하는 이유


  1. SQL 중심적인 개발에서 객체 중심적인 개발로 전환

  2. 생산성을 높일 수 있음

  3. 유지보수에서의 이점

  4. Object와 RDB 간의 패러다임 불일치 해결

  5. 특정 DBMS에 종속적이지 않음 (Dialect 기능으로 인해)

 

JPA Dialect 란?


  • JPA에서는 개발자가 직접 SQL을 작성하는 것이 아니라 JPA가 직접 SQL을 작성하고 실행하는 형태임
  • DBMS 종류별로 사용하는 SQL 문법이 조금씩 다름 (이를 SQL 방언이라고 함)
  • JPA에서는 Dialect라는 추상화된 방언 클래스를 제공하고 있어서 약간의 설정을 통해 자신의 DBMS에 맞는 SQL을 선택하기만 하면 JPA가 알아서 그에 맞는 쿼리를 생성해 줌
  • 즉, 개발자는 자신의 DBMS가 Mysql 이던, Oracle 이던, Mssql 이던 신경 쓸 필요가 없음

 

 

JPA의 내부구조


  • 엔티티 매니저 팩토리는 엔티티메니저를 생성하는 곳이며 웹 어플리케이션 내에 하나만 생성하고 전체에서 공유되는 자원이다.

  • 엔티티 매니저는 요청마다 새로 생성되며 각 요청간에(스레드간) 공유할 수 없다. (사용되면 버려야 함)

  • JPA의 모든 데이터 변경은 하나의 트랜잭션 내에서 수행된다.

 

영속성 컨텍스트란


  • '엔티티를 영구 저장하는 환경' 이라는 뜻

  • 논리적인 개념 (눈에 보이지 않음)

  • 엔티티 매니저 내에 영속성 컨텍스트가 내재해 있다고 생각하면 됨

스프링에서의 앤티티 매니저와 영속성 컨텍스트의 관계

  • 엔티티 매니저를 통해 영속성 컨텍스트에 접근할 수 있음

 

엔티티의 생명주기


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

  • 영속 (managed) : 영속성 컨텍스트에 저장된 상태

  • 준영속 (detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태

  • 삭제 (removed) : 삭제된 상태

 

영속성 컨텍스트를 사용하는 이유, 이점


  • 1차 캐시

  • 동일성 보장 (자바의 같은 Collection 내의 객체는 모두 동일한 것과 유사)

  • 트랜잭션을 지원하는 쓰기 지연 (sql을 최대한 모아놨다가 한번에 수행 가능, connection 사용 최소화)

  • 변경 감지 (Dirty Checking, 이로인해 entity를 set하기만 해도 저절로 테이블이 변경됨, 내부에 스냅샷을 따로 저장)

  • 지연 로딩(Lazy Loading)

1차 캐시

 

 

트랜잭션 단위의 쓰기지연

 

flush란?


  • 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영(동기화)하는 작업

  • flush를 실행시키는 방법

  • - 1. 직접 호출(em.flush)

  • - 2. 트랜잭션 커밋 - 플러시 자동 호출

  • - 3. JPQL 쿼리 싱행 - 플러시 자동 호출

  • 플러시는 영속성 컨텍스트를 비우지 않음

 

JPA의 패치전략


  • 지연로딩(LAZY) - 엔티티를 조회할 경우 연관된 엔티티를 실제 사용할 시 조회

  • 즉시로딩(EAGER) - 엔티티를 조회할 때 연관된 엔티티도 함께 조회

  • 연관된 두 테이블의 데이터가 항상 모두 같이 사용될 때는 EAGER 전략이 유리.

  • 실무에서는 모든 연관 테이블의 fetchType을 LAZY로 설정하고 다른 연관 테이블의 데이터가 필요할때마다 가져다가 쓰는 방식을 택하는 것이 일반적이다. (주로 패치 조인 많이 사용)

 

JPQL


  • Java Persistance Query Language

  • SQL과 비슷한 문법을 가진 객체지향 쿼리 (테이블이 아닌 객체를 검색하는 객체지향 쿼리)

  • JPA에서 제공되는 메서드 호출만으로는 섬세한 쿼리 작성에 한계가 있어서 나온 개념

 

@Query


  • @Query를 쓰는 이유는 @Query는 애플리케이션 로딩 시점에 쿼리를 파싱하기 때문

  • 즉, 런타임 시점이 아닌 컴파일 시점에 에러를 예방할 수 있다. (컴파일 시점에 나는 에러가 가장 처리하기 좋은 에러)

  • 즉, 개발하면서 실수를 사전에 없앨 수 있음

 

참고자료


  • 자바 ORM 표준 JPA 프로그래밍/김영한