2 분 소요

자바 ORM 표준 JPA 프로그래밍 정리

mylittlebible 개인 프로젝트를 진행하면서 JPA를 사용해 진행하던 도중 헷갈리는 부분이 있었고 책을 찾아보게 되었다. 내용을 찾아보면서 한번 읽었던 책을 다시한번 정리하기로 했다.


정리 내용

비즈니스 로직보다 SQL문 작성에 더 많은 시간을 사용하는 문제점발생

객체와 관계형 데이터베이스는 지향하는 목적이 서로 다름

  • 객체는 상속이란 기능이 있지만 데이터베이스는 슈퍼타입, 서브타입으로만 존재함

  • 객체는 참조를 통해 객체와 접근하지만 데이터베이스는 조인을 통해 테이블을 조회함
    • (가지고 있는 값이 무엇인가? 객체 <-> 외래키 Id값)
  • 객체와 연관된 객체를 조회할때 어디까지 탐색할 수 있는가
    • SQL문을 직접다루면 실행하는 SQL문에 따라 어디까지 탐색할수 있는지가 정해짐
  • 객체의 동등성과 동일성 , 테이블의 기본키값의 로우 비교
    • 같은 테이블에서 정보를 가져와 각각넣어도 객체는 동등성은 만족하지만 동일성은 만족하지 않음

이런 여러가지 차이점을 개발자가 해결하기 위해 시간을 소모해야하는데 이런 문제를 해결하기 위해 만든 결과물이 JPA.



JPA 란

Java Persistence Api 자바 진영의 ORM 기술 표준

ORM: Object-Relational Mapping 객체와 관계형 데이터베이스를 맵핑함

자바 애플리케이션과 JDBC API 사이에서 동작함

따라서 우리가 객체를 저장하고 싶을 때 SQL문을 작성하는게 아니라 마치 객체를 컬렉션에 저장하듯 사용할 수 있음



JPA 장점

  • 생산성: 자바 컬렉션에 객체를 저장하듯 JPA에게 저장할 객체를 전달함
  • 유지보수: 수정사항이 생길때 변경되는 코드가 줄어듬
  • 패러다임 불일치 해결: 서로 지향하는 목적이 다른 부분을 해결함
  • 성능: 애플리케이션과 데이터베이스 사이에서 성능 최적화 기회를 제공함
  • 데이터 접근 추상화: 특정 데이터베이스에 종속되지 않음
//테이블 생성 예시
CREATE TABLE MEMBER(
        ID VARCHAR(255) NOT NULL,
        NAME VARCHAR(255),
        AGE INTEGER,
        PRIMARY KEY (ID)
        )

//객체
@Table(name="MEMBER")
@Entity
public class Member{
    @Id
    private String id;

    private String name;
    
    private Integer age;
}

이 책에서는 설정으로 JDBC 드라이버, 아이디, 비밀번호, 데이터베이스 접속 URL, 데이터베이스 방언 설정함

앞서 JPA는 종속적이지 않기때문에 각데이터베이스마다 제공하는 문법이 상이할 수 있음 따라서 방언을 제공하여 방언만 교체하면 됨

예시 org.hibernate.dialect.H2Dialect org.hibernate.dialect.MYSQL5InnoDBDialect


진행 순서

엔티티 매니저 팩토리 생성 -> 엔티티 매니저 생성 -> 트랜잭션 가져오기 -> 트랜잭션을 시작하고 비즈니스 로직 실행 -> 트랜잭션 완료



영속성 컨텍스트

엔티티를 영구 저장하는 환경으로 엔티티 매니저를 사용하여 저장하고 싶은 객체를 저장함

종류

  • 비영속: 영속성 컨텍스트에 관련없는 상태
  • 영속: 영속성 컨텍스트에 저장된 상태
  • 준영속: 영속성 컨텍스트에 저장되었다가 분리된 상태
  • 삭제: 삭제된 상태




영속성 컨텍스트의 특징

  • 엔티티를 식별자값(@Id로 테이블의 기본키와 맵핑한 값)으로 구분하기에 반드시 식별자 값을 가져야 함
  • 영속성 컨텍스트에 저장된 엔티티가 데이터베이스에 반영되려면 flush()가 실행되야 함
  • 1차 캐시, 동일성 보장, 트랜잭션을 지원하는 쓰기 지연, 변경 감지, 지연 로딩


flush()

  • 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영함
    • 변경 감지 수행하여 스냅샷과 비교해 수정된 엔티티를 찾아 수정 쿼리를 쓰기 지연 SQL 저장소에 등록
    • 지연 저장소의 쿼리를 데이터베이스에 전송함

flush 호출방법 3가지(em.flush(), 트랜잭션 커밋, JPQL 쿼리 실행)

준영속 상태는 1차 캐시, 동일성 보장, 쓰기 지연, 변경 감지, 지연 로딩을 사용 불가함 대신 영속상태가 되었을때 만들었던 식별값은 가지고 있음

업데이트: