์ฐ๊ด๊ด๊ณ ๋งคํ ๊ธฐ์ด
๊ฐ์ฒด์ ํ ์ด๋ธ ์ฐ๊ด๊ด๊ณ์ ์ฐจ์ด๋ฅผ ์ดํดํ๋ค. ๊ฐ์ฒด์ ์ฐธ์กฐ์ ํ ์ด๋ธ์ ์ธ๋ ํค๋ฅผ ๋งคํํ๋ ๋ฐฉ๋ฒ์ ์ดํดํ๋ค.
์ฉ์ด ์ดํด
- ๋ฐฉํฅ: ๋จ๋ฐฉํฅ, ์๋ฐฉํฅ
- ๋ค์ค์ฑ: ๋ค๋์ผ, ์ผ๋๋ค, ์ผ๋์ผ, ๋ค๋๋ค
- ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ: ๊ฐ์ฒด ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ๋ ๊ด๋ฆฌ ์ฃผ์ธ์ด ํ์
์ฐ๊ด๊ด๊ณ๊ฐ ํ์ํ ์ด์
์์ ์๋๋ฆฌ์ค
- ํ์๊ณผ ํ์ด ์๋ค.
- ํ์์ ํ๋์ ํ์๋ง ์์๋ ์ ์๋ค.
- ํ์๊ณผ ํ์ ๋ค๋์ผ ๊ด๊ณ๋ค.
๊ฐ์ฒด๋ฅผ ํ ์ด๋ธ์ ๋ง์ถ์ด ๋ชจ๋ธ๋ง
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@Column(name = "TEAM_ID")
private Long teamId;
โฆ
}
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
โฆ
}
// ํ ์ ์ฅ
Team team = new Team();
team.setName("TeamA");
em.persist(team);
// ํ์ ์ ์ฅ
Member member = new Member();
member.setName("member1");
member.setTeamId(team.getId());
em.persist(member);
// ์กฐํ
Member findMember = em.find(Member.class, member.getId());
// ์ฐ๊ด๊ด๊ณ๊ฐ ์์
Team findTeam = em.find(Team.class, team.getId());
๊ฐ์ฒด๋ฅผ ํ ์ด๋ธ์ ๋ง์ถ์ด ๋ฐ์ดํฐ ์ค์ฌ์ผ๋ก ๋ชจ๋ธ๋งํ๋ฉด, ํ๋ ฅ ๊ด๊ณ๋ฅผ ๋ง๋ค ์ ์๋ค. ํ ์ด๋ธ์ ์ธ๋ ํค๋ก ์กฐ์ธ์ ์ฌ์ฉํด์ ์ฐ๊ด๋ ํ ์ด๋ธ์ ์ฐพ๋ ๋ฐ๋ฉด, ๊ฐ์ฒด๋ ์ฐธ์กฐ๋ฅผ ์ฌ์ฉํด์ ์ฐ๊ด๋ ๊ฐ์ฒด๋ฅผ ์ฐพ๋๋ค. ํ ์ด๋ธ๊ณผ ๊ฐ์ฒด ์ฌ์ด์๋ ์ด๋ฐ ํฐ ๊ฐ๊ฒฉ์ด ์กด์ฌํ๋ค.
๋จ๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ
๊ฐ์ฒด ์งํฅ ๋ชจ๋ธ๋ง
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
private int age;
// @Column(name = "TEAM_ID")
// private Long teamId;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
โฆ
}
//ํ ์ ์ฅ
Team team = new Team();
team.setName("TeamA");
em.persist(team);
//ํ์ ์ ์ฅ
Member member = new Member();
member.setName("member1");
member.setTeam(team); //๋จ๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ ์ค์ , ์ฐธ์กฐ ์ ์ฅ
em.persist(member);
//์กฐํ
Member findMember = em.find(Member.class, member.getId());
//์ฐธ์กฐ๋ฅผ ์ฌ์ฉํด์ ์ฐ๊ด๊ด๊ณ ์กฐํ
Team findTeam = findMember.getTeam();
// ์๋ก์ด ํB
Team teamB = new Team();
teamB.setName("TeamB");
em.persist(teamB);
// ํ์1์ ์๋ก์ด ํB ์ค์
member.setTeam(teamB);
์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ์ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ 1 - ๊ธฐ๋ณธ
์๋ฐฉํฅ ๋งคํ
๊ฐ์ฒด์ ์๋ฐฉํฅ ๊ด๊ณ
๊ฐ์ฒด์ ์๋ฐฉํฅ ๊ด๊ณ๋ ์ฌ์ค ์๋ฐฉํฅ ๊ด๊ณ๊ฐ ์๋๋ผ ์๋ก ๋ค๋ฅธ ๋จ๋ฐฉํฅ ๊ด๊ณ 2๊ฐ๋ค. ๊ฐ์ฒด๋ฅผ ์๋ฐฉํฅ์ผ๋ก ์ฐธ์กฐํ๋ ค๋ฉด ๋จ๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ 2๊ฐ๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค.
- ํ์ โ ํ
member.getTeam()
- ํ โ ํ์
team.getMembers()
ํ ์ด๋ธ์ ์๋ฐฉํฅ ๊ด๊ณ
ํ ์ด๋ธ์ ์ธ๋ ํค ํ๋๋ก ๋ ํ ์ด๋ธ์ ์ฐ๊ด๊ด๊ณ๋ฅผ ๊ด๋ฆฌํ๋ค. MEMBER.TEAM_ID ์ธ๋ ํค ํ๋๋ก ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ๋ฅผ ๊ฐ์ง๋ค.
- ํ์ โ โ ํ
SELECT * FROM MEMBER M JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
SELECT * FROM TEAM T JOIN MEMBER M ON T.TEAM_ID = M.TEAM_ID
๋ ์ค ํ๋๋ก ์ธ๋ ํค๋ฅผ ๊ด๋ฆฌํด์ผ ํจ
Member ์ Team ์ด๋ Team ์ members ์ค์ ์ด๋ค ๊ฐ์ด ๋ฐ๋ ๋ MEMBER.TEAM_ID ๋ฅผ ์
๋ฐ์ดํธ ํด์ผ ํ๋๊ฐ?
๋ ์ค์ ํ๋๊ฐ ์ธ๋ ํค๋ฅผ ๊ด๋ฆฌํ๋๋ก ์ ํด์ฃผ๋ ๊ฒ์ด ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ด๋ค.
์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ
๊ฐ์ฒด์ ๋ ๊ด๊ณ ์ค ํ๋๋ฅผ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ผ๋ก ์ง์ ํ๋ค. ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ๋ง์ด ์ธ๋ ํค๋ฅผ ๊ด๋ฆฌํ ์ ์์ผ๋ฉฐ, ์ฃผ์ธ์ด ์๋์ชฝ์ ์ฝ๊ธฐ๋ง ๊ฐ๋ฅํ๋ค.
- ์ฃผ์ธ์ mappedBy ์์ฑ์ ์ฌ์ฉํ์ง ์๋๋ค.
- ์ฃผ์ธ์ด ์๋๋ฉด mappedBy ์์ฑ์ผ๋ก ์ฃผ์ธ์ ์ง์ ํด์ผ ํ๋ค.
๊ทธ๋ฌ๋ฉด ๋๊ตฌ๋ฅผ ์ฃผ์ธ์ผ๋ก ์ ํด์ผํด?
์ธ๋ ํค๊ฐ ์๋ ๊ณณ์ ์ฃผ์ธ์ผ๋ก ์ ํด์ผํ๋ค.
DB ์์ ManyToOne ๊ด๊ณ์ผ ๊ฒฝ์ฐ, ํญ์ FK ๋ฅผ ๊ฐ๋ ์ชฝ์ Many ๊ฐ ๋๊ธฐ ๋๋ฌธ์, Many ์ชฝ์ด ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ด ๋๋ ๊ฒ์ด ์ข๋ค.
์ ์์์์๋ Member ์ Team ์ด ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ด ๋๋ ๊ฒ์ด๋ค.
์๋ฐฉํฅ ๋งคํ ์ ๊ฐ์ฅ ๋ง์ด ํ๋ ์ค์
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
// ์ญ๋ฐฉํฅ(์ฃผ์ธ์ด ์๋ ๋ฐฉํฅ)๋ง ์ฐ๊ด๊ด๊ณ ์ค์
team.getMembers().add(member);
em.persist(member);
์ ์ฝ๋ ์คํ ์ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ ๊ฐ์ ์
๋ ฅํ์ง ์์๊ธฐ ๋๋ฌธ์ member
์ team
์ null
์ด ๋๋ค.
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
member.setTeam(team); // ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์๋ง ๊ฐ ์ค์
em.persist(member);
team.getMembers(); // null
์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์๋ง ๊ฐ์ ๋ฃ์ด์ค๋ค๋ฉด, JPA ์ ์ํด mappedBy
์ชฝ์์๋ ๊ฐ์ ๊ฐ์ ธ์ฌ ์ ์์ง๋ง, 2๊ฐ์ง ๋ฌธ์ ์ ์ด ์์ ์ ์๋ค.
em.flush()
์ดํem.clear()
๋ฅผ ํ ๋ค DB ์์ ๊ฐ์ ๊ฐ์ ธ์จ๋ค๋ฉด ๋ฌธ์ ๊ฐ ์์ง๋ง, ์์์ฑ ์ปจํ ์คํธ์ Team ๊ณผ Member ๋ฅผ ์ ์ฅํ ๋ค ์ฌ์ฉํ ๊ฒฝ์ฐ,team.getMembers()
๋ฅผ ํธ์ถํ๋ค๋ฉดnull
๊ฐ์ด ๋ฐํ๋๋ค.- ํ ์คํธ ์ผ์ด์ค๋ ๋๋ถ๋ถ JPA ์์ด ์์ ์๋ฐ ์ฝ๋๋ก ์ด๋ฃจ์ด์ง๋๋ฐ, ์ด๋ด ๊ฒฝ์ฐ null ์ด ๋์ฌ ์ ์๋ค.
์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ ์ฃผ์
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
member.setTeam(team); // ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ ๊ฐ ์ค์
em.persist(member);
team.getMembers().add(member); // ์ญ๋ฐฉํฅ์๋ ๊ฐ ์ค์
- ์์์ ์ธ๊ธํ 2๊ฐ์ง ๋ฌธ์ ์ ๊ณผ ๋๋ถ์ด, ์ฌ์ฉ๋๋ ์ฝ๋๊ฐ ๊ฐ์ฒด์งํฅ์ ์ด์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ๊ฐ๊ธ์ ์ด๋ฉด ์ ์ฝ๋ ์ฒ๋ผ ์์ชฝ์ ๊ฐ์ ๋ค ๋ฃ์ด์ฃผ๋ ๊ฒ์ด ์ข๋ค.
public void changeTeam(Team team) {
this.team = team;
team.getMembers().add(this);
}
- ๋ํ, ์ฐ๊ด๊ด๊ณ ์ค์ ์ ์์ชฝ์ ๋ชจ๋ ๊ฐ์ ์ค์ ํ ์ ์๋๋ก ์ฐ๊ด๊ด๊ณ ํธ์ ๋ฉ์๋๋ฅผ ์์ฑํ์.
- ์๋ฐฉํฅ ๋งคํ ์
toString()
์ JSON ์์ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ ์member
์team
์ ์ฐธ์กฐํ๊ณteam
์member
๋ฅผ ์ฐธ์กฐํ๋ฉด์ ๋ฌดํ ๋ฃจํ๊ฐ ๋ฐ์ํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ฐ๊ธ์ ์ด๋ฉดtoString()
์ ์ฌ์ฉํ์ง ๋ง๊ณController
์๋ ์ํฐํฐ๋ฅผ ์ ๋ ๋ฐํํ์ง ์๋๋ก ํ์.Controller
๊ฐ DTO ๋ฅผ ๋ฐํํ๋ ์ด์ ๊ฐ ์ฌ๊ธฐ์ ์๋ค.
์๋ฐฉํฅ ๋งคํ ์ ๋ฆฌ
- ๋จ๋ฐฉํฅ ๋งคํ๋ง์ผ๋ก๋ ์ด๋ฏธ ์ฐ๊ด๊ด๊ณ ๋งคํ์ ์๋ฃ๋ ๊ฒ์ด๋ค.
- ์๋ฐฉํฅ ๋งคํ์ ๋ฐ๋ ๋ฐฉํฅ์ผ๋ก ์กฐํ(๊ฐ์ฒด ํ์ ๊ทธ๋ํ) ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋ ๊ฒ ๋ฟ์ด๋ค.
- JPQL ์์ ์ญ๋ฐฉํฅ์ผ๋ก ํ์ํ ์ผ์ด ๋ง๋ค.
- ๋จ๋ฐฉํฅ ๋งคํ์ ์ ํ๊ณ ์๋ฐฉํฅ์ ํ์ํ ๋ ์ถ๊ฐํด๋ ๋๋ค. ํ ์ด๋ธ์ ์ํฅ์ ์ฃผ์ง ์๋๋ค.
์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ ์ ํ๋ ๊ธฐ์ค
- ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ ์ธ๋ ํค์ ์์น๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ํด์ผํ๋ค.
์ค์ ์์ 2 - ์ฐ๊ด๊ด๊ณ ๋งคํ ์์
ํ ์ด๋ธ ๊ตฌ์กฐ
ํ
์ด๋ธ ๊ตฌ์กฐ๋ ์ด์ ๊ณผ ๊ฐ๋ค.
๊ฐ์ฒด ๊ตฌ์กฐ
์ฐธ์กฐ๋ฅผ ์ฌ์ฉํ๋๋ก ๋ณ๊ฒฝํ๋ค.
์ฐ๊ด๊ด๊ณ ๋งคํ ์ ๊ณ ๋ ค์ฌํญ 3๊ฐ์ง
๋ค์ค์ฑ
@ManyToOne
๋ค๋์ผ@OneToMany
์ผ๋๋ค@OneToOne
์ผ๋์ผ@ManyToMany
๋ค๋๋ค
๋จ๋ฐฉํฅ, ์๋ฐฉํฅ
ํ ์ด๋ธ
- ์ธ๋ ํค ํ๋๋ก ์์ชฝ ์กฐ์ธ ๊ฐ๋ฅ
- ์ฌ์ค ๋ฐฉํฅ์ด๋ผ๋ ๊ฐ๋ ์ด ์์ ๊ฐ์ฒด
- ์ฐธ์กฐ์ฉ ํ๋๊ฐ ์๋ ์ชฝ์ผ๋ก๋ง ์ฐธ์กฐ ๊ฐ๋ฅ
- ํ์ชฝ๋ง ์ฐธ์กฐํ๋ฉด ๋จ๋ฐฉํฅ
- ์์ชฝ์ด ์๋ก ์ฐธ์กฐํ๋ฉด ์๋ฐฉํฅ
์ฐ๊ด๊ด๊ณ ์ฃผ์ธ
- ํ ์ด๋ธ์ ์ธ๋ ํค ํ๋๋ก ๋ ํ ์ด๋ธ์ด ์ฐ๊ด๊ด๊ณ๋ฅผ ๋งบ์
- ๊ฐ์ฒด ์๋ฐฉํฅ ๊ด๊ณ๋ ์ฐธ์กฐ๊ฐ 2๊ตฐ๋ฐ ์์
- ๋ ์ค ํ ์ด๋ธ์ ์ธ๋ ํค๋ฅผ ๊ด๋ฆฌํ ๊ณณ์ ์ง์ ํด์ผ ํจ
- ์ฆ, ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ ์ธ๋ํค๋ฅผ ๊ด๋ฆฌํ๋ ์ฐธ์กฐ์ด๊ณ , ์ฃผ์ธ์ ๋ฐ๋ํธ์ ๋จ์ ์กฐํ๋ง ๊ฐ๋ฅ
๋ค๋์ผ [N:1]
๋ค๋์ผ ๋จ๋ฐฉํฅ
- ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ ์ฐ๊ด๊ด๊ณ
- ๋ค๋์ผ์ ๋ฐ๋๋ ์ผ๋๋ค
๋ค๋์ผ ์๋ฐฉํฅ
- ์ธ๋ ํค๊ฐ ์๋ ์ชฝ์ด ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ
- ์์ชฝ์ ์๋ก ์ฐธ์กฐํ๋๋ก ๊ฐ๋ฐ
์ผ๋๋ค [1:N]
์ผ๋๋ค ๋จ๋ฐฉํฅ
๊ฒฐ๋ก ๋ถํฐ ๋งํ์๋ฉด ์ด๋ฐ ๊ตฌ์กฐ๋ ๊ฑฐ์ ๊ฐ์ ธ๊ฐ์ง ์๋๋ค.
์ผ๋๋ค ๋จ๋ฑกํฅ์ ์ผ๋๋ค์์ ์ผ์ด ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ด ๋๋ค.
ํ์ง๋ง, ํ
์ด๋ธ ์ผ๋๋ค ๊ด๊ณ์์๋ ํญ์ ๋ค์ชฝ์ ์ธ๋ ํค๊ฐ ์กด์ฌํ๋ค.
์ด ๊ฒฝ์ฐ, ๊ฐ์ฒด์ ํ
์ด๋ธ์ ์ฐจ์ด ๋๋ฌธ์ ๋ฐ๋ํธ ํ
์ด๋ธ์ ์ธ๋ ํค๋ฅผ ๊ด๋ฆฌํ๋ ํน์ดํ ๊ตฌ์กฐ๊ฐ ๋๋ค.
Member member = new Member();
member.setUserName("member1");
em.persist(member);
Team team = new Team();
team.setName("teamA");
team.getMembers().add(member);
em.persist(team);
ํด๋น ์ฝ๋๋ฅผ ์คํํ์ ๊ฒฝ์ฐ, ํ ์ด๋ธ ์ ์ฅ์์๋ MEMBER ๊ฐ TEAM_ID ๋ฅผ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์, TEAM ์ ์ถ๊ฐํ๊ธฐ ์ํด MEMBER ํ ์ด๋ธ์ UPDATE ์ฟผ๋ฆฌ๊ฐ ์ถ๊ฐ๋ก ๋๊ฐ๊ฒ ๋๋ค.
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany
@JoinColumn(name = "TEAM_ID")
private List<Member> members = new ArrayList<>();
}
๋ํ, ์์ฒ๋ผ ์ผ๋๋ค ๊ด๊ณ๋ฅผ ๊ฐ๋ ์ปฌ๋ผ์ @JoinColumn
์ ๊ผญ ์ฌ์ฉํด์ผ ํ๋ค.
๊ทธ๋ ์ง ์์ผ๋ฉด TEAM_ID ์ MEMBER_ID ๋ฅผ ๊ฐ์ง๊ณ ์๋ ์ค๊ฐ ํ
์ด๋ธ์ ํ๋ ์ถ๊ฐํ์ฌ ์กฐ์ธ ํ
์ด๋ธ ๋ฐฉ์์ ์ฌ์ฉํ์ฌ ์ธ๋ ํค๋ฅผ ๊ด๋ฆฌํ๊ฒ ๋๋ค.
์ผ๋๋ค ๋จ๋ฐฉํฅ ์ ๋ฆฌ
์ผ๋๋ค ๋จ๋ฐฉํฅ ๋งคํ์ ๋จ์
- ์ํฐํฐ๊ฐ ๊ด๋ฆฌํ๋ ์ธ๋ ํค๊ฐ ๋ค๋ฅธ ํ ์ด๋ธ์ ์์
- ์ฐ๊ด๊ด๊ณ ๊ด๋ฆฌ๋ฅผ ์ํด ์ถ๊ฐ๋ก UPDATE SQL ์คํ ๋๋ฌธ์, ๊ฐ์ฒด์งํฅ์ ์ผ๋ก ์ํด๋ฅผ ๋ณด๋๋ผ๋ ์ผ๋๋ค ๋จ๋ฐฉํฅ ๋งคํ๋ณด๋ค๋ ๋ค๋์ผ ์๋ฐฉํฅ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ ๊ด๊ณ๋ก ๋ง๋ค์ด์ฃผ๋ ๊ฒ์ด ๋ ์ข์ ์ค๊ณ์ผ ์ ์๋ค.
์ผ๋๋ค ์๋ฐฉํฅ
์ด๋ฐ ๋งคํ์ ๊ณต์์ ์ผ๋ก ์กด์ฌํ์ง ์์ง๋ง ๋ง๋ค ์๋ ์๋ค.
์ด๋ฐ ๊ฒฝ์ฐ,
@JoinColumn(insertable=false, updatable=false)
๋ก ์ฝ๊ธฐ ์ ์ฉ ํ๋๋ฅผ ์ฌ์ฉํด์ ์๋ฐฉํฅ ์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ค.
์ด๋ฐ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋ณด๋ค๋ ๋ค๋์ผ ์๋ฐฉํฅ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
์ผ๋์ผ [1:1]
์ผ๋์ผ ๊ด๊ณ
์ผ๋์ผ ๊ด๊ณ๋ ๊ทธ ๋ฐ๋๋ ์ผ๋์ผ์ด๊ธฐ ๋๋ฌธ์ ๋์นญ ๊ด๊ณ๋ผ๊ณ ์๊ฐํด๋ณผ ์ ์๋ค. ๋๋ฌธ์, ์ฃผ ํ ์ด๋ธ์ด๋ ๋์ ํ ์ด๋ธ ์ค์ ํ ๊ณณ์์ ์ธ๋ ํค๋ฅผ ์ ํํ ์ ์๋ค. ํ ์ด๋ธ ๊ด์ ์์ ์ผ๋์ผ ๊ด๊ณ๋ฅผ ๊ตฌํํ๊ธฐ ์ํด์ ์ธ๋ ํค์ UNI ์ ์ฝ์กฐ๊ฑด์ด ์ถ๊ฐ๋์ด์ผ ํ๋ค.
์ฃผ ํ ์ด๋ธ์ ์ธ๋ ํค ๋จ๋ฐฉํฅ
@ManyToOne
๋จ๋ฐฉํฅ ๋งคํ๊ณผ ์ ์ฌํ๋ค๋ ๊ฒ์ ์ ์ ์๋ค.
์ฃผ ํ ์ด๋ธ์ ์ธ๋ ํค ์๋ฐฉํฅ
๋ค๋์ผ ์๋ฐฉํฅ ๋งคํ ์ฒ๋ผ ์ธ๋ ํค๊ฐ ์๋ ๊ณณ์ด ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ด ๋๋ฉฐ, ๋ฐ๋ํธ์
mappedBy
๋ฅผ ์ ์ฉํ๋ฉด ๋๋ค.
๋์ ํ ์ด๋ธ์ ์ธ๋ ํค ๋จ๋ฐฉํฅ
๋จ๋ฐฉํฅ ๊ด๊ณ๋ JPA ์์ ์ง์ํ์ง ์์ง๋ง, ์๋ฐฉํฅ ๊ด๊ณ๋ ์ง์ํ๋ค.
MEMBER ํ
์ด๋ธ์ ๋ง์ด SELECT ํ๋ค๋ ๊ฐ์ ํ์, MEMBER ๊ฐ LOCKER ๋ฅผ ๊ฐ์ง๊ณ ์๋ ๊ฒ์ด ๋ ํจ์จ์ ์ด๋ค.
๋์ ํ ์ด๋ธ์ ์ธ๋ ํค ์๋ฐฉํฅ
์ฌ์ค ์ผ๋์ผ ์ฃผ ํ
์ด๋ธ์ ์ธ๋ ํค ์๋ฐฉํฅ๊ณผ ๋งคํ ๋ฐฉ๋ฒ์ ๊ฐ๋ค.
์ผ๋์ผ ์ ๋ฆฌ
์ฃผ ํ
์ด๋ธ์ ์ธ๋ ํค๋ฅผ ์์น์ํค๋ฉด, ์ฃผ ๊ฐ์ฒด๊ฐ ๋์ ๊ฐ์ฒด์ ์ฐธ์กฐ๋ฅผ ๊ฐ์ง๋ ๊ฒ ์ฒ๋ผ ์ฃผ ํ
์ด๋ธ์ ์ธ๋ ํค๋ฅผ ๋๊ณ ๋์ ํ
์ด๋ธ์ ์ฐพ์ ์ ์๋ค.
์ด๋ ๊ฐ์ฒด์งํฅ ๊ฐ๋ฐ์๋ค์ด ์ ํธํ๋ ๋ฐฉ๋ฒ์ด๋ฉฐ, JPA ๋งคํ์ด ํธ๋ฆฌํ๋ค๋ ์ ์ด ์๋ค.
์ฃผ ํ
์ด๋ธ๋ง ์กฐํํด๋ ๋์ ํ
์ด๋ธ์ ๋ฐ์ดํฐ๊ฐ ์๋์ง ํ์ธ์ด ๊ฐ๋ฅํ๋ค๋ ์ฅ์ ์ด ์์ง๋ง, ๊ฐ์ด ์์ผ๋ฉด ์ธ๋ ํค์ null
์ ํ์ฉํ๋ค๋ ๋จ์ ์ญ์ ์กด์ฌํ๋ค.
๋์ ํ
์ด๋ธ์ ์ธ๋ ํค๋ฅผ ์์น์ํค๋ฉด, ์ฃผ ํ
์ด๋ธ๊ณผ ๋์ ํ
์ด๋ธ์ ์ผ๋์ผ์์ ์ผ๋๋ค ๊ด๊ณ๋ก ๋ณ๊ฒฝํ ๋ ๋ค์ชฝ์ด ๋๋ ํ
์ด๋ธ์ ์ด๋ฏธ ์ธ๋ ํค๊ฐ ์กด์ฌํ๊ธฐ ๋๋ฌธ์, ํ
์ด๋ธ ๊ตฌ์กฐ๋ฅผ ์ ์งํ๊ณ ๋ณ๊ฒฝํ ์ ์๋ค๋ ์ฅ์ ์ด ์กด์ฌํ๋ค.
ํ์ง๋ง, ํ๋ก์ ๊ธฐ๋ฅ์ ํ๊ณ๋ก ์ง์ฐ ๋ก๋ฉ์ผ๋ก ์ค์ ํด๋ ํญ์ ์ฆ์ ๋ก๋ฉ๋๋ ๋จ์ ์ญ์ ์กด์ฌํ๋ค.
๋ค๋๋ค [N:M]
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ ๊ทํ๋ ํ
์ด๋ธ 2๊ฐ๋ก ๋ค๋๋ค ๊ด๊ณ๋ฅผ ํํํ ์ ์๋ค.
์ด๋ฅผ ๊ตฌํํ๊ธฐ ์ํด ์ฐ๊ฒฐ ํ
์ด๋ธ์ ์ถ๊ฐํด์ ์ผ๋๋ค, ๋ค๋์ผ ๊ด๊ณ๋ก ํ์ด๋ด์ผ ํ๋ค.
๊ฐ์ฒด๋ ์ปฌ๋ ์
์ ์ฌ์ฉํด์ ๊ฐ์ฒด 2๊ฐ๋ก ๋ค๋๋ค ๊ด๊ณ๊ฐ ๊ฐ๋ฅํ๋ค.
@ManyToMany
์ @JoinTable
๋ก ์ฐ๊ฒฐ ํ
์ด๋ธ์ ์ง์ ํด์ ์ฌ์ฉํด์ผ ํ๋ค.
๋ค๋๋ค ๋งคํ์ ํ๊ณ
ํธ๋ฆฌํด ๋ณด์ด์ง๋ง ์ค๋ฌด์์ ์ฌ์ฉํ์ง ์๋๋ค. ์ฐ๊ฒฐ ํ ์ด๋ธ์ด ๋จ์ํ ์ฐ๊ฒฐ๋ง ํ๊ณ ๋๋์ง ์๊ณ , ์ฃผ๋ฌธ์๊ฐ, ์๋ ๊ฐ์ ๋ฐ์ดํฐ๊ฐ ๋ค์ด์ฌ ์ ์๋ค.
๋ค๋๋ค ํ๊ณ ๊ทน๋ณต
์ฐ๊ฒฐ ํ
์ด๋ธ์ ์ํฐํฐ๋ก ์น๊ฒฉ์์ผ ์ฐ๊ฒฐ ํ
์ด๋ธ์ฉ ์ํฐํฐ๋ฅผ ์ถ๊ฐํ๋ค.
@ManyToMany
โ @OneToMany
@ManyToOne
์ค์ ์์ 3 - ๋ค์ํ ์ฐ๊ด๊ฐ๊ณ ๋งคํ
N:M ๊ด๊ณ๋ 1:N, N:1 ๋ก ๋ณ๊ฒฝ
ํ ์ด๋ธ์ N:M ๊ด๊ณ๋ ์ค๊ฐ ํ ์ด๋ธ์ ์ด์ฉํด์ 1:N, N:1 ๋ก ๋ณ๊ฒฝํ๋ ๊ฒ์ด ์ข๋ค. ์ค์ ์์๋ ์ค๊ฐ ํ ์ด๋ธ์ด ๋จ์ํ์ง ์๊ธฐ ๋๋ฌธ์ N:M ์ ์ฌ์ฉํ์ง ์๋๋ค.
@JoinColumn
์ธ๋ ํค๋ฅผ ๋งคํํ ๋ ์ฌ์ฉํ๋ค.
name
๋งคํํ ์ธ๋ ํค ์ด๋ฆreferencedColumnName
์ธ๋ ํค๊ฐ ์ฐธ์กฐํ๋ ๋์ ํ ์ด๋ธ์ ์ปฌ๋ผ๋ชforeignKey(DDL)
์ธ๋ ํค ์ ์ฝ์กฐ๊ฑด์ ์ง์ ์ง์ ํ ์ ์์unique
nullable
insertable
updatable
columnDefinition
table
@Column ์ ์์ฑ๊ณผ ๊ฐ์
@ManyToOne
๋ค๋์ผ ๊ด๊ณ ๋งคํ ์ ์ฌ์ฉํ๋ค.
optional
false ๋ก ์ค์ ์ ์ฐ๊ด๋ ์ํฐํฐ๊ฐ ํญ์ ์์ด์ผ ํจfetch
๊ธ๋ก๋ฒ ํ์น ์ ๋ต์ ์ค์ cascade
์์์ฑ ์ ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉtargetEntity
์ฐ๊ด๋ ์ํฐํฐ ํ์ ์ ๋ณด๋ฅผ ์ค์ . ์ ๋ค๋ฆญ์ผ๋ก ํ์ ์ ๋ณด๋ฅผ ์ ์ ์๊ธฐ ๋๋ฌธ์ ๊ฑฐ์ ์ฌ์ฉํ์ง ์์
@OneToMany
๋ค๋์ผ ๊ด๊ณ ๋งคํ ์ ์ฌ์ฉํ๋ค.
mappedBy
์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ ํ๋๋ฅผ ์ ํfetch
๊ธ๋ก๋ฒ ํ์น ์ ๋ต์ ์ค์ cascade
์์์ฑ ์ ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉtargetEntity
์ฐ๊ด๋ ์ํฐํฐ ํ์ ์ ๋ณด๋ฅผ ์ค์ . ์ ๋ค๋ฆญ์ผ๋ก ํ์ ์ ๋ณด๋ฅผ ์ ์ ์๊ธฐ ๋๋ฌธ์ ๊ฑฐ์ ์ฌ์ฉํ์ง ์์
์์๊ด๊ณ ๋งคํ
๊ฐ์ฒด๋ ์์๊ด๊ณ๊ฐ ์์ง๋ง RDB ์๋ ์์๊ด๊ณ๊ฐ ์๋ค.
RDB ์ ์ํผํ์
์๋ธํ์
๊ด๊ณ๋ผ๋ ๋ชจ๋ธ๋ง ๊ธฐ๋ฒ์ด ๊ฐ์ฒด์ ์์๊ณผ ์ ์ฌํ๋ค.
์ฆ, ์์๊ด๊ณ ๋งคํ์ด๋, ๊ฐ์ฒด์ ์์๊ตฌ์กฐ์ RDB ์ ์ํผํ์
์๋ธํ์
๊ด๊ณ๋ฅผ ๋งคํํ๋ ๊ฒ์ ์๋ฏธํ๋ค.
์ํผํ์
์๋ธํ์
๋
ผ๋ฆฌ ๋ชจ๋ธ์ ์ค์ ๋ฌผ๋ฆฌ ๋ชจ๋ธ๋ก ๊ตฌํํ๋ ๋ฒ์ ์ด 3๊ฐ์ง๊ฐ ์กด์ฌํ๋ค.
- ์กฐ์ธ ์ ๋ต
- ๋จ์ผ ํ ์ด๋ธ ์ ๋ต
- ๊ตฌํ ํด๋์ค๋ง๋ค ํ ์ด๋ธ ์ ๋ต
์กฐ์ธ ์ ๋ต
@Inheritance*(*strategy = InheritanceType.JOINED*)*
@DiscriminatorColumn(name = "DTYPE")
๊ธฐ๋ณธ๊ฐ์ โDTYPEโ ์ด๋ฉฐ, ์์ ํ
์ด๋ธ์ ๊ตฌ๋ถํ๊ธฐ ์ํด DTYPE ์ด ์ถ๊ฐ๋๋ ๊ฒ์ด ์ข๋ค.
@DiscriminatorValue("XXX")
๊ธฐ๋ณธ๊ฐ์ โํด๋์ค๋ช
โ ์ด๋ฉฐ, ์์ ํ
์ด๋ธ์ ํ
์ด๋ธ๋ช
์ ๋ช
์ํด์ฃผ๊ณ ์ถ์ ๋ ์ฌ์ฉํ ์ ์๋ค.
์กฐ์ธ ์ ๋ต์ ์ฅ์ ์ผ๋ก๋, ํ
์ด๋ธ์ด ์ ๊ทํ ๋์ด์๊ณ , ์ธ๋ ํค ์ฐธ์กฐ ๋ฌด๊ฒฐ์ฑ ์ ์ฝ์กฐ๊ฑด์ ํ์ฉํ ์ ์์ผ๋ฉฐ, ํจ์จ์ ์ผ๋ก ์ ์ฅ๊ณต๊ฐ์ ์ฌ์ฉํ ์ ์๋ค๋ ์ ์ด ์๋ค.
๋ฐ๋ฉด, ๋จ์ ์ผ๋ก๋, ์กฐํ ์ ์กฐ์ธ์ ๋ง์ด ์ฌ์ฉ๋์ด ์ฑ๋ฅ์ด ์ ํ๋๊ณ , ๋ฐ์ดํฐ ์ ์ฅ ์ INSERT ์ฟผ๋ฆฌ๊ฐ 2๋ฒ ํธ์ถ๋๋ ์ ์ด ์๋ค.
๊ฐ์ฒด์ ์์๊ณผ ๊ฐ์ฅ ์ ์ฌํ๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ์ ์ผ๋ก , ์กฐ์ธ ์ ๋ต์ด ์ ์์ด๋ผ๊ณ ์๊ฐํ๋ ๊ฒ์ด ์ข๋ค.
๋จ์ผ ํ ์ด๋ธ ์ ๋ต
@Inheritance*(*strategy = InheritanceType.SINGLE_TABLE*)*
๋จ์ผ ํ
์ด๋ธ ์ ๋ต์ ๋ชจ๋ ์์ ํ
์ด๋ธ ์์๋ฅผ ํ ํ
์ด๋ธ์์ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ์์ ํ
์ด๋ธ์ ๊ตฌ๋ถํ๊ธฐ ์ํ์ฌDTYPE ๋ฅผ ์๋์ผ๋ก ์ถ๊ฐํด์ค๋ค.
๋จ์ผ ํ
์ด๋ธ ์ ๋ต์ ์ฅ์ ์ผ๋ก๋, ์กฐ์ธ์ด ํ์ ์๊ธฐ์ ์ผ๋ฐ์ ์ผ๋ก ์กฐํ๊ฐ ๋น ๋ฅด๋ค๋ ์ ์ด ์๋ค.
๋ฐ๋ฉด, ๋จ์ ์ผ๋ก๋, ์์ ์ํฐํฐ๊ฐ ๋งคํํ ์ปฌ๋ผ์ ๋ชจ๋ null ์ ํ์ฉํด์ผํ๋ฉฐ, ๋จ์ผ ํ
์ด๋ธ์ ๋ชจ๋ ๊ฒ์ ์ ์ฅํ๊ธฐ ๋๋ฌธ์ ์ํฉ์ ๋ฐ๋ผ ์กฐํ ์ฑ๋ฅ์ด ์คํ๋ ค ๋๋ ค์ง ์ ์๋ค๋ ์ ์ด ์๋ค.
๊ตฌํ ํด๋์ค๋ง๋ค ํ ์ด๋ธ ์ ๋ต
@Inheritance*(*strategy = InheritanceType.TABLE_PER_CLASS*)*
๋ถ๋ชจ ํ
์ด๋ธ์ด ์๊ธฐ ๋๋ฌธ์
Item
ํ์
์ผ๋ก ์กฐํ ์ ๋ชจ๋ ์์ ํ
์ด๋ธ์ ๋ค์ ธ์ ๊ฒฐ๊ณผ๋ฅผ ์ฐพ๋๋ค.
์ด ์ ๋ต์ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์ข๋ค.
@MappedSuperclass - ๋งคํ ์ ๋ณด ์์
@MappedSuperclass
public abstract class BaseEntity {
private String createdBy;
private LocalDateTime createdDate;
private String lastModifiedBy;
private LocalDateTime lastModifiedDate;
}
๊ณตํต ๋งคํ ์ ๋ณด๊ฐ ํ์ํ ๋ ์ฌ์ฉํ๋ค. ์ฆ, ์์ฑ๋ง ์์๋ฐ์์ ์ฐ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค. ํ ์ด๋ธ๊ณผ ๊ด๊ณ ์์ด ๋จ์ํ ์ํฐํฐ๊ฐ ๊ณตํต์ผ๋ก ์ฌ์ฉํ๋ ๋งคํ ์ ๋ณด๋ฅผ ๋ชจ์ผ๋ ์ญํ ์ด๋ค. ์ฃผ๋ก ๋ฑ๋ก์ผ, ์์ ์ผ, ๋ฑ๋ก์, ์์ ์ ๊ฐ์ ์ ์ฒด ์ํฐํฐ์์ ๊ณตํต์ผ๋ก ์ ์ฉํ๋ ์ ๋ณด๋ฅผ ๋ชจ์ ๋ ์ฌ์ฉํ๋ค. ์ง์ ์์ฑํด์ ์ฌ์ฉํ ์ผ์ด ๊ฑฐ์ ์๊ธฐ ๋๋ฌธ์ ์ถ์ ํด๋์ค๋ฅผ ๊ถ์ฅํ๋ค.
์ค์ ์์ 4 - ์์๊ด๊ณ ๋งคํ
๋๋ฉ์ธ ๋ชจ๋ธ