[ZB_BOOK STUDY] 스프링 부트 핵심 가이드 (9)

Dreamer·2024년 4월 21일
0
post-thumbnail

📖 스프링 부트 핵심 가이드

: 스프링 부트를 활용한 애플리케이션 개발 실무


📝 목차

9장. 연관관계 매핑

9-1. 연관관계 매핑 종류와 방향
9-2. 프로젝트 생성
9-3. 일대일 매핑
- 일대일 단방향 매핑
- 일대일 양방향 매핑

9-4. 다대일, 일대다 매핑
- 다대일 단방향 매핑
- 다대일 양방향 매핑
- 일대다 단방향 매핑

9-5. 다대다 매핑
- 다대다 단방향 매핑
- 다대다 양방향 매핑

9-6. 영속성 전이
- 영속성 전이 적용
- 고아 객체

9-7. 정리


9장. 연관관계 매핑

테이블의 연관관계를 설정해서 엔티티 간의 연관관계로 표현
객체와 테이블의 성질이 달라 정확한 연관관계를 표현할 수 없다
JPA에서 이러한 제약을 보완하면서 연관관계를 매핑하고 사용하는 방법 알아보자

9-1. 연관관계 매핑 종류와 방향

연관관계를 맺는 두 엔티티 간에 생성할 수 있는 연관관계의 종류

  • One To One : 일대일 (1:1)
  • One To Many : 일대다 (1:N)
  • Many To One : 다대일 (N:1)
  • Many To Many : 다대다 (N:M)

예시로 이해해보자
한 가게가 재고관리 시스템을 통해 상품을 관리
: 상품 테이블과 공급업체 테이블의 관계

  • 상품 테이블 = 재고 상품의 정보 엔티티
  • 공급업체 테이블 = 가게에 상품을 공급하는 업체정보 엔티티
✅ 공급업체 입장 
➞ 한 가게에 납품하는 상품이 여러개 있을 수 있으므로 상품 엔티티와는 일대다 관계

✅ 상품 입장 
➞ 하나의 공급업체에 속하게 되므로 다대일 관계

어떤 엔티티를 중심으로 연관 엔티티를 보느냐에 따라 연관관계의 상태가 달라짐!

데이터베이스에서는 두 테이블의 연관관계를 설정하면 외래키를 통해 서로 조인해서 참조하는 구조로 생성
JPA를 사용하는 객체지향 모델링에서는 엔티티 간 참조방향을 설정할 수 있다.

  • 단방향 : 두 엔티티의 관계에서 한쪽의 엔티티만 참조하는 형식
  • 양방향 : 두 엔티티의 관계에서 엔티티가 서로의 엔티티를 참조하는 형식

연관관계가 설정되면 한 테이블에서 다른 테이블의 기본값을 외래키로 갖게 됩니다.
이런 관계에서는 주인(Owner)이라는 개념이 사용됩니다.
일반적으로 외래키를 가진 테이블이 그 관계의 주인이 되며, 주인은 외래키를 사용할 수 있으나 상대 엔티티는 읽는 작업만 수행할 수 있습니다.

9-2. 프로젝트 생성

9-3. 일대일 매핑

One To One : 일대일 (1:1)
: 하나의 상품에 하나의 상품 정보만 매핑되는 구조

일대일 단방향 매핑

@OneToOne 어노테이션
: 다른 엔티티 객체를 필드로 정의했을 때, 일대일 연관관계로 매핑하기 위해 사용
@JoinColumn 어노테이션
: 매핑할 외래키를 설정

@JoinColumn 어노테이션 속성값
☑️ name 
: 매핑할 외래키의 이름을 설정
☑️ referencedColumnName 
: 외래키가 참조할 상대 테이블의 컬럼명을 지정
☑️ foreignKey 
: 외래키를 생성하면서 지정할 제약조건을 설정 
(unique, nullable, insertable, updatable등)

즉시 로딩 : 엔티티를 조회할 때 연관된 엔티티도 함께 조회하는 것

일대일 양방향 매핑

: 양쪽에서 단방향으로 서로를 매핑하는 것을 의미

⭐ 양방향으로 연관관계가 설정되면 ToString을 사용할 때 순환참조가 발생
필요한 경우가 아니라면 대체로 단방향으로 연관관계를 설정하거나
양방샹 설정이 필요한 경우에는 순환참조 제거를 위해 exclude를 사용해 ToString에서 제외설정을 하기

9-4. 다대일, 일대다 매핑

상품 테이블과 공급업체 테이블을 예시로
상품 테이블 입장에서는 다대일
공급업체 테이블의 입장에서 볼 때는 일대다 관계로 볼 수 있다.

  • 다대일 단방향 매핑
  • 다대일 양방향 매핑 : 양쪽에서 단방향으로 매핑하는 것
  • 일대다 단방향 매핑

🍀 Tip. 지연로딩과 즉시로딩
지연로딩(lazy loading), 즉시로딩(eager loading)

엔티티라는 객체의 개념으로 데이터베이스를 구현했기 때문에
연관관계를 가진 각 엔티티 클래스에는 연관관계가 있는 객체들이 필드에 존재하게 됩니다.

연관관계와 상관없이 즉각 해당 엔티티의 값만 조회하고 싶거나
연관관계를 가진 테이블의 값도 조회하고 싶은 경우 등 여러조건들을 만족하기 위해 등장한 개념
-> 지연로딩과 즉시로딩

일대다 단방향 매핑

@OneToMany@JoinColumn을 사용하면 상품 엔티티에서 별도의 설정을 하지 않아도 일대다 단방향 연관관계가 매핑됩니다.

@JoinColumn 어노테이션 ⭢ 필수 사항은 아니다.
이 어노테이션을 사용하지 않으면 중간 테이블로 Join테이블이 생성되는 전략 채택

9-5. 다대다 매핑

: 다대다 연관관계는 실무에서 거의 사용되지 않는 구성입니다.

예를 들면, 한 종류의 상품이 여러 생산업체를 통해 생산 될 수 있고,
생산업체 한 곳이 여러 상품을 생산 할 수도 있습니다.

다대다 연관관계에서는 각 엔티티에서 서로를 리스트로 가지는 구조
이런 경우에는 교차 엔티티라고 부르는 ⭐중간 테이블⭐을 생성해서 다대다 관계를 일대다 또는 다대일 관계로 해소합니다.

다대다 단방향 매핑

@ManyToMany 어코테이션으로 설정으로 설정
리스트로 필드를 가지는 객체에서는 외래키를 가지지 않기 때문에 별도의 @JoinColumn은 설정하지 않아도 된다.

다대다 양방향 매핑

다대다 연관관계 설정 ⭢ 중간 테이블을 통해 연관된 엔티티의 값을 가져올 수 있다

<다대다 양방향 매핑의 한계>
다대다 연관관계에서는 중간 테이블이 생성되기 때문에 예기치 못한 쿼리가 생길 수 있다. = 관리하기 힘들다.

✅ 중간테이블을 생성하는 대신, 일대다 다대일로 연관관계를 맺을 수 있는 중간 엔티티로 승격시켜 JPA에서 관리하도록 생성하는 게 좋다.

9-6. 영속성 전이 (cascade)

: 특정 엔티티의 영속성 상태를 변경할 때,
그 엔티티와 연관된 엔티티의 영속성에도 영향을 미쳐 영속성 상태를 변경하는 것

예를 들어 @OneToMany 어노테이션의 인터페이스 살펴보기
연관관계와 관련된 어노테이션을 보면 cascade() 요소를 볼 수 있다.
이 어노테이션은 영속성 전이를 설정하는 데 활용된다.

  • cascade() 요소와 함께 사용하는 영속성 전이 타입
종류설명
ALL모든 영속 상태 변경에 대해 영속성 전이를 적용
PERIST엔티티가 영속화할 때 연관된 엔티티도 함께 영속화
MERGE엔티티를 영속성 컨텍스트에 병합할 때 연관된 엔티티도 병합
REMOVE엔티티를 제거할 때 연관된 엔티티도 제거
REFRESH엔티티를 새로고침할 때 연관된 엔티티도 새로고침
DETACH엔티티를 영속성 컨텍스트에서 제외하면 연관된 엔티티도 제외

영속성 전이에 사용되는 타입은 엔티티 생명주기와 연관이 있습니다.
한 엔티티가 cascade 요소의 값으로 주어진 영속 상태의 변경이 일어나면
매핑으로 연관된 엔티티에도 동일한 동작이 일어나도록 전이를 발생시키는 것 입니다.

영속성의 전이 적용

✅ 영속성의 전이 사용 전 ⭢ 엔티티를 데이터베이스에 저장하기 위해 각 엔티티를 저장하는 코드를 작성해야 함

✅ 영속성 전이 사용 ⭢ 부모 엔티티가 되는 엔티티만 저장하면 코드에 작성돼 있는 Cascade.PERSIST에 맞춰 상품 엔티티도 함께 저장할 수 있음

이처럼 특정 상황에 맞춰 영속성 전이 타입을 설정하면
영속 상태의 변화에 따라 연관된 엔티티들의 동작도 함께 수행할 수 있어 ⭐개발의 생산성 증대

<사용 시 주의할 점>
자동 설정으로 동작하는 코드들이 정확히 어떤 영향을 미치는지 반드시 파악할 것
예를 들어,
REMOVE와 REMOVE를 포함하는 ALL같은 타입은 연관된 엔티티가 의도치 않게 모두 삭제될 위험성이 있어 다른 타입보다 더욱 사이드 이펙트(side effect)를 고려해서 사용해야 한다.

고아 객체

: JPA에서 고아(orphan)란 부모 엔티티와 연관관계가 끊어진 엔티티를 의미
JPA에는 이러한 고아 객체들을 자동으로 제거하는 기능이 존재

고아 객체를 제거하는 기능을 사용하려면
@OneToMany 어노테이션 속성에 orphanRemoval속성을 true로 설정

9-7. 정리

profile
Moving forward based on records

0개의 댓글