21 Jul 2022

[Spring] JPA 공부

JPA는 표준 ORM(Object-Relational Mapping)으로 Hibernate라는 ORM 프레임워크를 사용해서 구현한다.

EntityManagerFactory 는 리소스를 많이 사용하기 때문에 하나만 생성에서 애플리케이션 내부에서 전체 공유해서 사용

EntityManager은 한번 쓰고 버려야 함. 여러 쓰레드에서 공유하면 안된다.

JPA의 모든 데이터 변경은 트랜잭션 안에서 실행

JPQL

  • SQL를 추상화한 객체지향 버전

JPQL : 엔티티 객체를 대상으로 쿼리

SQL : 데이터베이스 대상으로 쿼리

영속성 컨텍스트

JPA를 이해하는 데 가장 중요한 용어

엔티티를 영구 저장하는 환경

영속성 컨텍스트는 논리적인 개념

엔티티 매니저를 통해 영속성 컨텍스트에 접근

엔티티의 생명주기

  • 비영속(new/transient)

​ 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태

  • 영속(managed)

​ 영속성 컨텍스트에 관리되는 상태

  • 준영속(detached)

​ 영속성 컨텍스트에 저장되었다가 분리된 상태

  • 삭제(removed)

​ 삭제된 상태

영속성 컨텍스트란?

Entity와 DB 사이를 연결해 주는 임시 저장 공간이라고 생각하면 쉽다.

Java – 영속성 컨텍스트(1차 캐시) – DB

데이터를 저장할 때 영속성 컨텍스트에 저장되고,

` 데이터를 요청할 때 영속성 컨텍스트에 저장된다.`

이렇게 해서 여러번 쿼리를 날릴 필요 없이 필요한 쿼리만 전송할 수 있다.(1차 캐시에 해당 데이터가 있으면 그것을 사용하면 되기 때문에)

영속성 컨텍스트(1차 캐시)는 트랜잭션 내에 있으며 트랜잭션이 초기화되면 데이터가 삭제된다.

쿼리를 실행하면 1차 캐시에 저장되고, 트랜잭션이 끝날 때 쿼리가 DB로 날라가서 정보를 저장/요청 한다.

  • 쓰기 지연
  • 변경 감지

플러시 flush()

영속성 컨텍스트의 변경내용을 DB에 동기화하는 작업

플러시가 되는 경우

  • em.flush() - 직접호출
  • transaction commit - 플러시 자동 호출
  • JPQL 쿼리 실행 - 플러시 자동 호출

주의점 : 영속성 컨텍스트를 비우지 않음!

준영속 상태

영속성 콘텍스트를 초기화 하는 것

영속 상태의 엔티티가 영속성 컨텍스트에서 분리

엔티티 @Entity

JPA가 관리한다

테이블과 매핑할 클래스

주의사항

기본생성자 필수

final, enum, interface, inner 클래스 사용 X

엔티티 매핑 어노테이션

어노테이션 설명
@Column 컬럼
@Temporal 날짜 타입
@Enumerated enum 타입
@Lob BLOB, CLOB 타입 매핑
@Transient 특정 필드를 Table 컬럼에서 제외

권장하는 식별자 전략

기본 키 제약 조건: null X, 유일, 변하면 안된다.

미래까지 이 조건을 만족하는 자연키는 찾기 어려움. 대체키 사용

권장 : Long형 + 대체키 + 키 생성전략 사용(auto increment, sequence 전략 등..)

엔티티 연관관계

다중성, 방향성, 연관관계 주인 설정을 해주어야 함

테이블에서는 기본적으로 양방향 연관관계가 적용됨 (Join)

하지만, 객체에서는 단방향 연관관계임

이 상황에서 양방향으로 설정했을 경우 어떤 테이블 기준으로 데이터를 삭제하면 그것에 관련된 데이터들을 다 삭제할 것인가? 라는 물음에서 답으로 연관관계 주인 설정이 나타남

양방향 매핑 규칙

객체의 두 관계 중 하나의 연관 관계를 주인으로 지정

주인만이 외래 키 관리(등록, 수정)

주인이 아닌 쪽은 읽기만 가능

주인은 mappedby 속성 X

외래 키(FK)가 있는 곳을 주인을 설정해 준다.
'다' 쪽이 주인이다.
@ManyToOne 은 항상 주인이다.

JpaRepository

  • Read : find** 로 시작
  • Delete : delete** 로 시작
  • Create : save
  • Update : 객체 조회 후 값 변경 그리고 다시 save

Builder 패턴에서 객체 생성할 때 Tip

설계자가 객체를 생성할 떄 순서를 고려하지 않을 때를 방지, 생성자 앞에 @Builder 어노테이션을 작성.

Thank You For Reading
SeungJun Jeon

점점 강해지고 있습니다.

comments powered by Disqus