본문 바로가기
GDSC Kookmin 22 - 23 Backend Study

11/21 GDSC 백엔드 스터디 정리

by 달리는 꿈나무 2022. 11. 26.

목차

1.  JPA

 

2.  Data JPA

 

 

JPA

 

영속성 컨택스트

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

 

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

 

EntityManager.persist(entity);

 

 

 

엔티티 매니저 팩토리와 엔티티 매니저

 

엔티티 매니저 팩토리와 엔티티 매니저

엔티티 매니저와 엔티티 매니저 팩토리

 

 

 

엔티티와 엔티티의 생명주기

엔티티 ==> 테이블에 대응하는 하나의 클래스

  • 비영속(new/transient) -> 영속성 컨택스트와 전혀 관계가 없는 새로운 상태
  • 영속(managed) -> 영속성 컨택스트에 관리되는 상태
  • 준영속(detached) -> 영속성 컨택스트에 저장되었다가 분리된 상태
  • 삭제(removed) -> 삭제된 상태

 

 

비영속

 

비영속 상태

 

 

영속

영속 상태

 

 

영속성 컨택스트의 이점

  • 1차 캐시
  • 동일성(identity)보장
  • 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)
  • 변경 감지(Dirty Checking)
  • 지연 로딩(Lazy Loading)

 

 

 

엔티티 수정 - 변경 감지

엔티티 - 수정 변경 감지

 

 

플러시

영속성 컨텍스트의 변경 내용을 데이터베이스에 반영

 

em.flush() - 직접 호출

 

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

 

JPQL 쿼리 실행 - 플러시 자동 호출

 

영속성 컨택스트를 비우지 않음

 

영속성 컨택스트의 변경 내용을 데이터베이스에 동기화

 

트랜잭션이라는 작업 단위가 중요 -> 커밋 직전에만 동기화하면 됨

 

 

 

 

엔티티 매핑

  • 객체와 테이블 매핑: @Entity, @Table
  • 필드와 컬럼 매핑: @Column
  • 기본 키 매핑: @Id
  • 연관관계 매핑: @ManyToOne, @JoinColumn

 

 

@Entity

  • @Entity가 붙은 클래스는 JPA가 관리, 엔티티라 한다.
  • JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 필수
  • 주의
    • 기본 생성자 필수(파라키터가 없는 public 또는 protected 생성자)
    • final 클래스, enum, interface, inner 클래스 사용X
    • 저장할 필드에 final 사용 X

 

 

 

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

  • DDL을 애플리케이션 실행 시점에 자동 생성
  • 테이블 -> 객체 중심
  • 데이터베이스 방언을 활용해서 데이터베이스에 맞는 적절한 DDL 생성
  • 이렇게 생성된 DDL은 개발 장비에서만 사용
  • 생성된 DDL은 운영서버에서는 사용하지 않거나, 적절히 다듬은 후 사용

 

 

 

@Column

@Column - 속성

 

 

 

기본 키 매핑 어노테이션

  • @Id
  • @GeneratedValue

 

 

 

기본 키 매핑 방법

  • 직접 할당: @Id만 사용
  • 자동 생성(@GenereatedValue)
    • IDENTITY: 데이터베이스에 위임, MYSQL
    • SEQUENCE: 데이터베이스 시퀀스 오브젝트 사용, ORACLE
      • @SequenceGenerator 필요
    • TABLE: 키 생성용 테이블 사용, 모든 DB에서 사용
      • @TableGenerator 필요
    • AUTO: 방언에 따라 자동 지정, 기본값

 

 

 

객체 지향 모델링(객체 연관 관계 사용)

연관관계

 

 

 

 

객체 지향 모델링(객체의 참조와 테이블의 외래 키를 매핑)

스프링 코드로 연관관계 맺기

 

 

 

 

 

양방향 매핑

양방향 매핑 연관관계

 

 

 

 

양방향 매핑(Team 엔티티는 컬렉션 추가)

스프링 연관관계 - 양방향 매핑

 

 

 

 

연관관계의 주인과 mappedBy

  • mappedBy = JPA의 멘탈붕괴 난이도
  • mappedBy는 처음에는 이해하기 어렵다.
  • 객체와 테이블 간에 연관관계를 맺는 차이를 이해해야한다.

 

 

 

 

객체와 테이블이 관계를 맺는 차이

  • 객체 연관관계 = 2개
    • 회원 -> 팀 연관관계 1개(단방향)
    • 팀 -> 회원 연관관계 1개(단방향)
  • 테이블 연관관계 = 1개
    • 회원 <-> 팀의 연관관계 1개(양방향)

 

 

 

객체의 양방향 관계

  • 객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개다.
  • 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 한다.
  • A -> B (a.getB()) | class A { B b };
  • B -> A (b.getA()) | class B { A a };

 

 

 

 

테이블의 양방향 연관관계

  • 테이블 외래 키 하나로 두 테이블의 연관관계를 관리
  • MEMBER.TEAM_ID 외래 키 하나로 양방향 연관관계 가짐(양 쪽으로 조인할 수 있다.)
    • SELECT * FROM MEMBER M JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
    • SELECT * FROM TEAM T JOIN MEMBER M ON T.TEAM_ID = M.TEAM_ID

 

 

 

 

연관관계 외래키 관리

둘 중 하나로 외래 키를 관리해야 한다.

연관관계 - 외래키 관리

 

 

 

 

연관관계의 주인(Owner)

양방향 매핑 규칙

  • 객체의 두 관계 중 하나를 연관관계의 주인으로 지정
  • 연관관계의 주인 만이 외래키를 관리(등록, 수정)
  • 주인이 아닌 쪽은 읽기만 가능
  • 주인 mappedBy 속성 사용X
  • 주인이 아니면 mappedBy 속성으로 주인 지정

 

 

 

 

누구를 주인으로?

  • 외래 키가 있는 곳을 주인으로 정해라
  • 여기서는 Member.team이 연관관계의 주인

연관관계의 주인 설정

 

 

 

 

다중성

  • 다대일: @ManyToOne
  • 일대다: @OneToMany
  • 일대일: @OneToOne
  • 다대다: @ManyToMany

 

 

 

다대다

  • 관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없음
  • 연결테이블을 추가해서 일대다, 다대일 관계로 풀어내야함

다대다 관계 => 일대다 - 테이블 - 다대일 관계

 

 

 

다대다 매핑의 한계

  • 편리해 보이지만 실무에서 사용X
  • 연결 테이블이 단순히 연결만 하고 끝나지 않음
  • 주문 시간, 수량같은 데이터가 들어올 수 있음

다대다는 실제로 없다.

 

 

 

 

다대다 한계 극복

  • 연결 테이블용 엔티티 추가(연결 테이블을 엔티티로 승격)
  • @ManyToMany -> @OneToMany, @ManyToOne

다대다 한계 극복