[JPA] 기본편 복습 정리 (1)

bin1225·2023년 2월 5일
0

JPA

목록 보기
8/12
post-thumbnail

JPA

JPA 등장 배경

관계형 DB를 사용하려면 SQL문을 사용하는데,
관계형 DB와 객체지향 언어는 패러다임의 차이가 있다.

  • 1. 상속관계

RDB에서는 상속관계를 표현하면, FK를 통해 부모테이블과 연관관계를 맺는다.
하지만 이렇게 한다고 해서 객체의 상속관계를 구현할 수 있는 게 아니다.

예를 들어 위 그림에서 객체 Album을 DB에 저장한다면, Item에 대한 정보를 Item 테이블에, Album에 대한 정보를 Album 테이블에 각각 INSERT 해줘야 한다.
조회 과정에서도 각 테이블에 join SQL을 작성해주고, 각 객체를 생성해주는 복잡한 과정을 거친다.

    1. 연관관계

      연관관계의 경우도 객체는 참조값을 RDB는 FK값을 이용하는 차이가 있다.
      이러한 차이로 데이터를 저장, 조회하는 과정에서 계속 FK값을 가져와 이용하는 번거로움이 생기고, 조회 이후에도 각 객체를 생성하고 연관관계를 설정해주는 작업을 해줘야 한다.

여기까지만 봐도 SQL에 의존적이게 되어, 객체지향의 장점이 퇴색되고 있는 게 느껴진다.

또 모든 연관된 객체를 미리 로딩할 수는 없기 때문에, 객체 그래프 탐색 과정에서 엔티티 신뢰 문제도 발생한다.
ex) 가져온 Member 객체에 Team에 대한 정보가 주입돼있는지 신뢰할 수 없다.

    1. 데이터 타입
      DB와 java언어는 데이터 타입이 다르다.
    1. 데이터 식별 방법
//DB애서 조회
String memberId = "100";
Member member1 = memberRepository.getMember(memberId);
Member member2 = memberRepository.getMember(memberId);

member == member2; // false

//객체에서 조회
String memberId = "100";
Member member1 = list.get(memberId);
Member member2 = list.get(memberId);

member == member2; // true

이러한 객체와 RDB의 패러다임 차이를 극복하기 위해 JPA를 이용한다.

JPA (Java Persistence API)

  • JPA
    Java ORM 기술 표준
    ORM : Object relational mapping
    객체와 관계형 데이터베이스의 정보를 중간에서 매핑해주는 기술이다.

    JPA는 인터페이스의 모음으로, Hibernate, EclipseLink, DataNucleus 등 구현체가 존제한다.

영속성 컨텍스트

JPA에서 가장 중요한 핵심 개념중 하나이다.
영속성 컨텍스트는 논리적인 개념
객체를 1차 캐시에 저장해두고, transaction이 끝나는 시점에서 commit 할 때 한 번에 데이터를 처리한다.

em.persist를 통해 객체를 영속시킨다.

이렇게 했을 때 이점은 다음과 같다.
• 1차 캐시
• 동일성(identity) 보장

영속화하면, 1차 캐시에 id값으로 구분하여 Entity를 저장한다.
그리고 조회시 1차캐시를 먼저 확인한 후 없으면 DB를 조회하는 구조이다.
따라서 같은 Transaction안에서는 동일성이 보장된다.

영속성 컨텍스트를 활요한 기능

  • 트랜잭션을 지원하는 쓰기 지연 (transactional write-behind) : commit 시점에 한 번에 1차캐시에 있는 데이터들을 처리한다.

  • 변경 감지 (Dirty Checking)
    DB에서 데이터를 조회하면 자동으로 해당 객체를 영속성 컨텍스트로 관리한다.
    영속성 컨텍스트에서 관리되는 객체는 수정시 자동으로 변경이 감지돼어(Dirty Checking) 값이 변경된다. -> update 쿼리를 따로 날릴 필요가 없어진다.

  • 지연 로딩 (Lazy Loading)
    프록시를 이용한 지연로딩이 가능해진다. 뒤에서 설명

    영속성 컨텍스트를 플러시 하는 방법

플러시 : 영속성 컨텍스트의 내용을 DB에 반영

em.flush() - 직접 호출
• 트랜잭션 커밋 - 플러시 자동 호출
• JPQL 쿼리 실행 - 플러시 자동 호출
-> 1차 캐시의 내용을 모두 반영한 상태에서 DB정보를 이용해야 한다.

준영속 상태로 만드는 방법

준영속 : 영속성 컨텍스트에서 엔티티를 분리시킨다. -> 영속성 컨텍스트가 제공하는 기능을 사용할 수 없다.
• em.detach(entity)
특정 엔티티만 준영속 상태로 전환
• em.clear()
영속성 컨텍스트를 완전히 초기화
• em.close()
영속성 컨텍스트를 종료


엔티티 매핑

객체와 테이블 매핑

@Entity가 붙은 클래스는 JPA가 관리, 엔티티라고 한다.

주의점

- 기본 생성자가 필수
- 저장할 필드에 final을 사용하면 안된다.

name 속성으로 이름을 지정할 수 있지만, 기본값(클래스 이름)사용을 권장

@Table : 엔티티와 매핑할 테이블 지정 (기본값 = 엔티티 이름)

데이터베이스 스키마 자동 생성

JPA는 DDL을 애플리케이션 실행 시점에 자동으로 생성한다.
데이터베이스 방언을 활용해서 사용하는 DB에 맞게 DDL이 생성된다.

실제 운영서버에서는 적절히 다듬은 후 사용해야 한다.

  • 속성
    - create : DROP + CREATE
    - create-drop : DROP + CREATE + DROP
    - update : 변경 부분만 반영
    - validate : 엔티티와 테이블이 정상 매핑되었는지만 확인
    - none : 사용하지 않음

운영 장비에는 create, create-drop, update 를 사용하면 안된다.
데이터가 전부 날아가버릴 위험이 있다.

@Column의 속성을 통해 제약조건을 추가할 수 있다.
nullable, length, 유니크 제약조건 등

필드와 컬럼 매핑

  • @Column : 컬럼 매핑

  • @Temporal : 날짜 타입 매핑
    속성
    - TEmporalType.DATE : 날짜, 데이터베이스 date 타입과 매핑
    ex) 2013-10-11
    - TemporalType.TIME : 시간, 데이터베이스 time타입과 매핑
    ex) 11:12:13
    - TemporalType.TIMESTAMP : 날짜와 시간, 데이터베이스 timestamp타입과 매핑
    ex) 2013-10-11 11:12:13
    LocalDate, LocalDateTime을 사용할 때는 생략 가능

  • @Enumerated : enum 타입 매핑
    속성 : EnumType.ORDINAL, EnumType.STRING
    -> 주의 : ORDINAL 속성을 사용하지 않는다. 순서로 저장시 추후 순서가 바뀌면 문제가 된다.

  • @Lob : BLOB, CLOB 매핑

  • @Transient : 매핑하지 않음
    메모리상에서 임시로 어떤 값을 보관하고 싶을 때 사용한다.

기본 키 매핑

  • @Id : 기본키 지정
  • @GeneratedValue : 자동 생성

속성

  • IDENTITY : 데이터베이스에 위임, MYSQL
  • SEQUENCE : 데이터베이스 시퀀스 오브젝트 사용, ORACLE
    - @SequenceGenerator 필요
    - allocationSize를 조절하여 최적화 할 수 있다.
  • TABLE: 키 생성용 테이블 사용, 모든 DB에서 사용
    - @TableGenerator 필요
  • AUTO: 방언에 따라 자동 지정, 기본값

기본 키 제약 조건 : NOT NULL, 유일성, 불변성
비즈니스 로직에서 사용하는 값은 불변성을 보장하기 힘들다.
-> Long + 대체키 + 키 생성 전략 을 권장한다.

0개의 댓글

관련 채용 정보