Skip to content

Commit b5ebb8c

Browse files
authored
feat: Add Chapter05.md (#7)
1 parent 8e21b97 commit b5ebb8c

1 file changed

Lines changed: 137 additions & 0 deletions

File tree

chapter05/해성/Chapter05.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# 5장 연관관계 매핑 기초
2+
3+
> 객체의 참조와 테이블의 외래키를 매핑
4+
5+
방향 : 한쪽만 참조하면 단방향 관계, 서로 참조하면 양방향 관계
6+
다중성 : 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(M:N)
7+
연관관계의 주인 : 객체를 연관관계로 만들면 연관관계의 주인을 정해야 한다. 연관관계의 주인은 테이블의 외래키가 있는 곳이다.
8+
9+
## 5.1 단방향 연관관계
10+
11+
객체 연관관계 : 회원 객체는 `Member.team` 필드로 팀 객체와 연관관계를 맺는다. (단방향)
12+
테이블 연관관계 : 회원 테이블은 `TEAM_ID` 외래키로 팀 테이블과 연관관계를 맺는다.(양방향, 정확히는 서로 다른 단방향 2개)
13+
14+
```sql
15+
SELECT *
16+
FROM MEMBER M
17+
JOIN TEAM T ON M.TEAM_ID = T.ID
18+
19+
SELECT *
20+
FROM TEAM T
21+
JOIN MEMBER M ON T.ID = M.TEAM_ID
22+
```
23+
24+
연관된 데이터를 조회할 때 객체는 참조를 사용하지만 테이블은 조인을 사용한다.
25+
26+
### 객체 그래프 탐색
27+
객체는 참조를 사용해서 연관관계를 탐색할 수 있는데, 이것을 객체 그래프 탐색이라고 한다.
28+
29+
### 조인
30+
데이터베이스는 외래 키를 사용해서 연관관계를 탐색할 수 있는데 이것을 조인이라 한다.
31+
32+
## 객체 관계 매핑
33+
```java
34+
@Entity
35+
public class Member {
36+
@Id
37+
@GeneratedValue
38+
private String id;
39+
40+
// 연관관계 매핑
41+
@ManyToOne // 다대일 관계라는 매핑 정보
42+
@JoinColumn(name = "TEAM_ID") // 외래키 매핑시 사용. 생략가능
43+
private Team team;
44+
45+
// ...
46+
}
47+
```
48+
```java
49+
@Entity
50+
public class Team {
51+
@Id
52+
@Column(name = "TEAM_ID")
53+
private String id;
54+
55+
private String name;
56+
57+
// ...
58+
}
59+
```
60+
61+
### @JoinColumn
62+
63+
| Modifier and Type | Optional Element | Description |
64+
|-|-|-|
65+
| java.lang.String | columnDefinition | (Optional) The SQL fragment that is used when generating the DDL for the column. |
66+
| ForeignKey | foreignKey | (Optional) Used to specify or control the generation of a foreign key constraint when table generation is in effect. |
67+
| boolean | insertable | (Optional) Whether the column is included in SQL INSERT statements generated by the persistence provider. |
68+
| java.lang.String | name | (Optional) The name of the foreign key column. |
69+
| boolean | nullable | (Optional) Whether the foreign key column is nullable. |
70+
| java.lang.String | referencedColumnName | (Optional) The name of the column referenced by this foreign key column. |
71+
| java.lang.String | table | (Optional) The name of the table that contains the column. |
72+
| boolean | unique | (Optional) Whether the property is a unique key. |
73+
| boolean | updatable | (Optional) Whether the column is included in SQL UPDATE statements generated by the persistence provider. |
74+
75+
https://docs.jboss.org/hibernate/jpa/2.2/api/javax/persistence/JoinColumn.html
76+
77+
### @ManyToOne
78+
79+
| Modifier and Type | Optional Element | Description |
80+
|-|-|-|
81+
| CascadeType[] | cascade (Optional) The operations that must be cascaded to the target of the association. |
82+
| FetchType | fetch | (Optional) Whether the association should be lazily loaded or must be eagerly fetched. |
83+
| boolean | optional | (Optional) Whether the association is optional. |
84+
| java.lang.Class | targetEntity | (Optional) The entity class that is the target of the association. |
85+
86+
https://docs.jboss.org/hibernate/jpa/2.2/api/javax/persistence/ManyToOne.html
87+
88+
## 연관관계 사용
89+
### 저장
90+
### 수정
91+
### 삭제
92+
93+
## 양방향 연관관계
94+
### 매핑
95+
### 조회
96+
97+
## 연관관계의 주인
98+
두 객체 연관관계 중 하나를 정해서 테이블의 외래키를 관리해야하는데 이것을 연관관계의 주인(Owner)이라 한다.
99+
연관관계의 주인만이 데이터베이스의 연관관계와 매핑되고 외래 키를 관리(등록, 수정, 삭제)할 수 있따. 반면에 주인이 아닌 쪽은 읽기만 할 수 있다.
100+
연관관계의 주인을 정한다는 것은 사실 외래 키 관리자를 선택하는 것이다. (객체 입장)
101+
102+
## 양방향 연관관계 유의점
103+
가장 흔히 하는 실수는 연관관계의 주인에는 값을 입력하지 않고, 주인이 아닌 곳에만 값을 입력하는 것이다.
104+
105+
### 순수한 객체까지 고려한 양방향 연관관계
106+
객체 관점에서 양쪽 방향에 모두 값을 입력해주는 것이 가장 안전하다.
107+
108+
### 연관관계 편의 메서드
109+
```java
110+
public class Member {
111+
private Team team;
112+
113+
/**
114+
* 양방향 관계를 모두 설정
115+
* 실수로 하나만 호출해서 양방향 연관관계가 깨지는 것을 방지
116+
*/
117+
public void setTeam(Team team) {
118+
// 기존 팀이 있으면 삭제
119+
if (this.team != null) {
120+
this.team.getMembers().remove(this);
121+
}
122+
this.team = team;
123+
team.getMembers().add(this); // 디미터의 법칙
124+
}
125+
}
126+
```
127+
128+
https://johngrib.github.io/wiki/law-of-demeter/
129+
130+
## 정리
131+
- 단방향 매핑만으로 테이블과 객체의 연관관계 매핑은 이미 완료되었다.
132+
- 단방향을 양방향으로 만들면 반대방향으로 객체 그래프 탐색 기능이 추가된다.
133+
- 양방향 연관관계를 매핑하려면 객체에서 양쪽 방향을 모두 관리해야 한다.
134+
- 연관관계의 주인은 외래키의 위치와 관련해서 정해야지 비즈니스 중요도로 접근하면 안된다.
135+
- 양방향 매핑시에는 무한루프에 빠지지 않게 조심해야한다.
136+
137+

0 commit comments

Comments
 (0)