Miracle Morning, LHWN

2. 연관관계매핑 본문

IT 기술/[JAVA] Spring Boot

2. 연관관계매핑

Lee Hye Won 2021. 5. 5. 10:57

연관관계 매핑

객체의 참조와 테이블의 외래키를 매핑하는 것이다. 연관관계 매핑하는 방법은 아래와 같다.

(1) ORM : 참조를 사용, 방향성이 있다.

(2) RDB : 외래키 (Join Key) 를 사용하며 항상 양방향이다.

(3) 방향은 단방향/양방향이 있다.

(4) 1:1, N:1, 1:N, N:N 관계로 다중성이 있다.

(5) 객체를 양방향 연관관계로 만들려면 연관관계의 주인이 필요하다.

 

# 다대일 (N:1) 연관관계

- user 와 team 이 있고, user 는 하나의 team 만 소속 가능하다.

- user 와 team 은 다대일 관계이다.

 

(1) 객체 연관관계

- User 객체는 User.team 필드로 team 객체와 연관관계를 맺는다.

- User 객체와 Team 객체는 단방향 관계이다.

https://fastcampus.co.kr/courses/204729/clips/

(2) 테이블 연관관계

- User 테이블은 team_id 외래키를 통해서 Team 테이블과 연관관계를 맺는다.

- User 와 Team 은 양방향 관계이다.

https://fastcampus.co.kr/courses/204729/clips/

 

# 객체 연관관계 vs 테이블 연관관계

- 테이블은 외래키를 이용해 연관관계를 맺는다.

- 객체는 참조를 이용해 연관관계를 맺는다.

- 테이블 연관관계는 항상 양방향이다.

- 객체 연관관계는 항상 단방향이다. (양방향이라는 것은 사실상 두 개의 단방향 연관관계이다.)

 

# 엔티티의 연관관계를 맺을 때 사용하는 annotation

(1) @ManyToOne (N:1)

(2) @OneToMany (1:N)

(3) OneToOne (1:1)

(4) ManyToMany (N:N)

 

ㄴ속성

(1) optional : false 로 설정 시 연관된 엔티티가 항상 있어야 한다. (Default 는 true)

(2) fetch : 글로벌 페치 전략을 설정한다.

  - FetchType.EAGER : 엔티티를 가져올 때 연관된 엔티티를 함께 가지고 온다.

  - FetchType.LAZY : 연관된 엔티티가 사용되는 순간에 연관된 엔티티를 가지고 온다.

 

# 외래키를 매핑할 때 사용하는 annotation

@JoinColumn

 

ㄴ속성

(1) name : 매핑할 외래키 이름을 지정한다. (Default 는 '필드명_참조테이블의 기본키 컬럼명' 이다.)

 

# 양방향 연관관계

https://fastcampus.co.kr/courses/204729/clips/

User → Team 뿐만 아니라, Team User 로 접근이 가능하다.

 

# 연관관계의 주인 (mappedBy 속성) 

객체에는 양방향 연관관계가 없다. 서로 다른 두 개의 단방향 연관관계만이 있을 뿐이다.

 

테이블은 외래키 하나로 두 테이블의 연관관계를 관리한다.

엔티티를 단방향으로 매핑할 경우 참조를 하나만 사용하므로 이 참조로 외래키를 관리하면 되나,

양방향일 경우 서로 참조를 하기 때문에 연관관계를 관리하는 포인트가 두 군데로 늘어난다.

 

이러한 문제를 해결하기 위해 JPA 는 두 객체의 연관관계 중 하나를 정해서 테이블의 외래키를 관리하는데 이를 '연관관계의 주인' 이라고 한다.

 

연관관계의 주인을 정한다 = 외래키 관리자를 선택한다.

 

- 연관관계는 주인만 등록/수정/삭제를 할 수 있고, 주인이 아닌 쪽은 읽기만 가능하다.

- 연관관계의 주인은 mappedBy 속성이 없는 쪽이고, 주인이 아닌 쪽은 mappedBy 를 설정해주어야 한다.

- DB 테이블의 1:N 관계에서 외래키는 항상 N 쪽에 있기 때문에 객체 양방향 관계에서 연관관계의 주인은 항상 N 쪽이다.

 

# 일대다 (1:N) 연관관계

- 일대다 관계는 엔티티를 하나 이상 참조할 수 있으므로 컬렉션을 사용한다.

- 단, 매핑한 객체가 관리하는 외래키가 다른 테이블에 있기 때문에 연관관계 처리를 위한 UPDATE SQL 을 추가로 실행해야한다.

 

# 일대일 (1:1) 연관관계

- 테이블에서 일대다 / 다대일 관계는 항상 '다' 쪽에 외래키가 있지만, 일대일의 경우는 어느 테이블이든 외래키를 가질 수 있다.

- 외래키 관리

  (1) 주테이블에서 관리 : 주 객체가 대상 객체를 참조하는 것처럼 주 테이블에 외래키를 두고 대상 테이블을 참조한다.

  (2) 대상 테이블에서 관리 : 테이블 관계를 일대일에서 일대다로 변경할 때 구조를 그대로 유지할 수 있다.

 

# 다대다 (N:N) 연관관계

- RDB 에서는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다.

이러한 경우 다대다 매핑을 위해 @JoinTable annotation 을 통해 연결 테이블을 설정하여 사용한다.

 

# 고급 매핑

(1) 상속 관계 매핑 : 객체의 상속관계를 DB 에 매핑하는 방법

@MappedSuperclass annotation 을 통해 '등록일, 수정일' 과 같은 여러 엔티티에서 공통으로 사용하는 매핑 정보만 상속받을 수 있다.

 

(2) 복합키와 식별 관계 매핑 : DB의 식별자가 하나 이상일 때 매핑하는 방법

 

(3) 조인 테이블 : 테이블 연관관계를 위해 연결 테이블을 매핑하는 방법 (엔티티 하나에 여러 테이블 매핑)

 

# @MappedSuperclass

부모 클래스는 테이블과 매핑하지 않고 부모 클래스를 상속받는 자식 클래스에게 매핑 정보만 제공하고 싶을 때 사용한다.

추상 클래스의 개념과 비슷하며, @Entity 는 실제 테이블과 매핑되지만 @MappedSuperclass 는 테이블과 매핑되지 않는다.

연관관계를 재정의할 때는 @AssociationOverride 를 사용한다.

 

출처 : fastcampus.co.kr/courses/204729/clips/

Comments