Skip to content

Commit

Permalink
feat: Add Chapter05.md (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
junhaesung authored Sep 8, 2021
1 parent 8e21b97 commit b5ebb8c
Showing 1 changed file with 137 additions and 0 deletions.
137 changes: 137 additions & 0 deletions chapter05/해성/Chapter05.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# 5장 연관관계 매핑 기초

> 객체의 참조와 테이블의 외래키를 매핑
방향 : 한쪽만 참조하면 단방향 관계, 서로 참조하면 양방향 관계
다중성 : 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(M:N)
연관관계의 주인 : 객체를 연관관계로 만들면 연관관계의 주인을 정해야 한다. 연관관계의 주인은 테이블의 외래키가 있는 곳이다.

## 5.1 단방향 연관관계

객체 연관관계 : 회원 객체는 `Member.team` 필드로 팀 객체와 연관관계를 맺는다. (단방향)
테이블 연관관계 : 회원 테이블은 `TEAM_ID` 외래키로 팀 테이블과 연관관계를 맺는다.(양방향, 정확히는 서로 다른 단방향 2개)

```sql
SELECT *
FROM MEMBER M
JOIN TEAM T ON M.TEAM_ID = T.ID

SELECT *
FROM TEAM T
JOIN MEMBER M ON T.ID = M.TEAM_ID
```

연관된 데이터를 조회할 때 객체는 참조를 사용하지만 테이블은 조인을 사용한다.

### 객체 그래프 탐색
객체는 참조를 사용해서 연관관계를 탐색할 수 있는데, 이것을 객체 그래프 탐색이라고 한다.

### 조인
데이터베이스는 외래 키를 사용해서 연관관계를 탐색할 수 있는데 이것을 조인이라 한다.

## 객체 관계 매핑
```java
@Entity
public class Member {
@Id
@GeneratedValue
private String id;

// 연관관계 매핑
@ManyToOne // 다대일 관계라는 매핑 정보
@JoinColumn(name = "TEAM_ID") // 외래키 매핑시 사용. 생략가능
private Team team;

// ...
}
```
```java
@Entity
public class Team {
@Id
@Column(name = "TEAM_ID")
private String id;

private String name;

// ...
}
```

### @JoinColumn

| Modifier and Type | Optional Element | Description |
|-|-|-|
| java.lang.String | columnDefinition | (Optional) The SQL fragment that is used when generating the DDL for the column. |
| ForeignKey | foreignKey | (Optional) Used to specify or control the generation of a foreign key constraint when table generation is in effect. |
| boolean | insertable | (Optional) Whether the column is included in SQL INSERT statements generated by the persistence provider. |
| java.lang.String | name | (Optional) The name of the foreign key column. |
| boolean | nullable | (Optional) Whether the foreign key column is nullable. |
| java.lang.String | referencedColumnName | (Optional) The name of the column referenced by this foreign key column. |
| java.lang.String | table | (Optional) The name of the table that contains the column. |
| boolean | unique | (Optional) Whether the property is a unique key. |
| boolean | updatable | (Optional) Whether the column is included in SQL UPDATE statements generated by the persistence provider. |

https://docs.jboss.org/hibernate/jpa/2.2/api/javax/persistence/JoinColumn.html

### @ManyToOne

| Modifier and Type | Optional Element | Description |
|-|-|-|
| CascadeType[] | cascade (Optional) The operations that must be cascaded to the target of the association. |
| FetchType | fetch | (Optional) Whether the association should be lazily loaded or must be eagerly fetched. |
| boolean | optional | (Optional) Whether the association is optional. |
| java.lang.Class | targetEntity | (Optional) The entity class that is the target of the association. |

https://docs.jboss.org/hibernate/jpa/2.2/api/javax/persistence/ManyToOne.html

## 연관관계 사용
### 저장
### 수정
### 삭제

## 양방향 연관관계
### 매핑
### 조회

## 연관관계의 주인
두 객체 연관관계 중 하나를 정해서 테이블의 외래키를 관리해야하는데 이것을 연관관계의 주인(Owner)이라 한다.
연관관계의 주인만이 데이터베이스의 연관관계와 매핑되고 외래 키를 관리(등록, 수정, 삭제)할 수 있따. 반면에 주인이 아닌 쪽은 읽기만 할 수 있다.
연관관계의 주인을 정한다는 것은 사실 외래 키 관리자를 선택하는 것이다. (객체 입장)

## 양방향 연관관계 유의점
가장 흔히 하는 실수는 연관관계의 주인에는 값을 입력하지 않고, 주인이 아닌 곳에만 값을 입력하는 것이다.

### 순수한 객체까지 고려한 양방향 연관관계
객체 관점에서 양쪽 방향에 모두 값을 입력해주는 것이 가장 안전하다.

### 연관관계 편의 메서드
```java
public class Member {
private Team team;

/**
* 양방향 관계를 모두 설정
* 실수로 하나만 호출해서 양방향 연관관계가 깨지는 것을 방지
*/
public void setTeam(Team team) {
// 기존 팀이 있으면 삭제
if (this.team != null) {
this.team.getMembers().remove(this);
}
this.team = team;
team.getMembers().add(this); // 디미터의 법칙
}
}
```

https://johngrib.github.io/wiki/law-of-demeter/

## 정리
- 단방향 매핑만으로 테이블과 객체의 연관관계 매핑은 이미 완료되었다.
- 단방향을 양방향으로 만들면 반대방향으로 객체 그래프 탐색 기능이 추가된다.
- 양방향 연관관계를 매핑하려면 객체에서 양쪽 방향을 모두 관리해야 한다.
- 연관관계의 주인은 외래키의 위치와 관련해서 정해야지 비즈니스 중요도로 접근하면 안된다.
- 양방향 매핑시에는 무한루프에 빠지지 않게 조심해야한다.


0 comments on commit b5ebb8c

Please sign in to comment.