kwonslog / how-to-use-jpa

0 stars 0 forks source link

연관관계 - 참조키 방식과 키 공유 방식의 차이점 #8

Closed kwonslog closed 1 month ago

kwonslog commented 5 months ago

참조키 방식

단방향 연관 맵핑 예제

CREATE TABLE Order ( id INT PRIMARY KEY AUTO_INCREMENT, order_number VARCHAR(255) NOT NULL, total_amount DECIMAL(10, 2) NOT NULL, customer_id INT );


- Order 엔티티 클래스 정의

@Entity @Table(name = "Order") public class Order { ...생략

@OneToOne
@JoinColumn(name = "customer_id")
private Customer customer;

...생략

}

- 특징
  - 두 엔티티는 독립된 생명주기를 가질 수 있다.
    > `독립된 생명주기란?` : 각 엔티티가 서로의 상태에 영향을 미치지 않고 독립적으로 생성, 업데이트, 삭제될 수 있음을 의미
  - 연관 관계 관리가 비교적 단순하며, 데이터베이스 설계 관행과 일치한다.

## 키 공유 방식
- 두 엔티티가 동일한 기본키 값을 공유하도록 맵핑하는 것이다.

### 키 공유 방식의 코드를 작성 할때 두 가지 방식으로 가능하다
 - `@PrimaryKeyJoinColumn`
   - 두 엔티티가 같은 기본 키 값을 공유하지만, 외래 키가 별도로 존재하도록 설정한다.
   - 두 엔티티가 서로 독립적인 기본 키를 유지하면서 연관 관계를 맺을 때 사용 할 수 있다.
 - `@MapsId`
   - 한 엔티티의 기본 키를 다른 엔티티의 기본 키로 직접 사용. 즉, 두 엔티티는 동일한 기본 키 값을 공유한다.
   - 주로 부모-자식 관계에서 자식이 부모의 기본 키를 자신의 기본 키로 사용할 때 사용 할 수 있다.

<details>
<summary>:question: 두 가지 방식은 어떤 기준으로 구분하여 사용해야 할까?</summary>

- `@MapsId` : 강하게 연결된 1:1 관계에 적합하다. 예를 들어, User와 UserProfile 같이 서로 없어서는 안 될 관계일 때 사용 할 수 있다.
- `@PrimaryKeyJoinColumn` : 1:1 관계에서도 사용할 수 있지만, 두 엔티티가 더 독립적일 때 사용 할수 있다. 예를 들어, 두 엔티티가 밀접한 관계는 아니지만 기술적으로 1:1 맵핑을 가지는 경우에 적합하다.

</details>

### 단방향 연관 맵핑 예제
- DB 테이블 정의

CREATE TABLE User ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL );

CREATE TABLE UserProfile ( id INT PRIMARY KEY, full_name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, FOREIGN KEY (id) REFERENCES User(id) );

- UserProfile 엔티티 클래스 정의

import javax.persistence.*;

@Entity public class UserProfile { ...생략

@Id
@OneToOne
@PrimaryKeyJoinColumn(name = "id")
private User user; // UserProfile의 기본 키가 User의 기본 키를 참조

...생략

}



## 차이점
- 키 공유 방식은 일반적으로 두 엔티티가 더 밀접한 관계에 있을 때 사용한다.
  예를 들어, 부모-자식 관계에서 자식 엔티티는 부모 엔티티 없이 존재하기 어려울 때 이 방식을 사용 할 수 있다.
- 키 공유 방식은 두 엔티티가 서로를 더 강하게 참조하기 때문에 한 엔티티의 변경이 다른 엔티티에 직접적인 영향을 미칠 수 있다.

- 참조키 방식은 전통적인 데이터베이스 설계와 비슷하다. 외래키를 사용하여 관계를 표현하는 것은 일반적인 관계형 데이터베이스 설계 방식이기 때문이다.
> 일반적으로 `@MapsId`가 `@PrimaryKeyJoinColumn`보다 더 널리 사용되며 이는 키 공유 방식을 구현하는 데 더 간결하고 효율적인 방법을 제공하기 때문이라고 한다.