๊น์ํ๋์ ์๋ฐ ORM ํ์ค JPA ํ๋ก๊ทธ๋๋ฐ์ ์ฝ๊ณ ์ ๋ฆฌํ ๊ธ์ ๋๋ค.
1. ์ํฐํฐ ์ฐ๊ด๊ด๊ณ ๋งคํ
๋ค์ค์ฑ
- ๋ค๋์ผ(@ManyToOne)
- ์ผ๋๋ค(@OneToMany)
- ์ผ๋์ผ(@OneToOne)
- ๋ค๋๋ค(@ManyToMany)
๋จ๋ฐฉํฅ, ์๋ฐฉํฅ
- ๋จ๋ฐฉํฅ: ๊ฐ์ฒด ๊ด๊ณ์์ ํ์ชฝ๋ง ์ฐธ์กฐ
- ์๋ฐฉํฅ: ๊ฐ์ฒด ๊ด๊ณ์์ ์์ชฝ์ด ์๋ก ์ฐธ์กฐ
์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ
- ๋ ๊ฐ์ฒด ์ฐ๊ด๊ด๊ณ ์ค ์ธ๋ ํค๋ฅผ ๊ด๋ฆฌํ๋ ์ชฝ์ ์ฃผ์ธ์ด๋ผ ํจ
- ์ธ๋ ํค๋ฅผ ๊ฐ์ง ํ ์ด๋ธ๊ณผ ๋งคํํ ์ํฐํฐ๋ฅผ ๋ณดํต ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ผ๋ก ์ ํ
- ์ฃผ์ธ์ด ์๋ ๋ฐฉํฅ์ ์ธ๋ ํค ๋ณ๊ฒฝ ๋ถ๊ฐ, ์ฝ๊ธฐ๋ง ๊ฐ๋ฅ
- ์ฃผ์ธ์ด ์๋ ์ชฝ์ mappedBy ์์ฑ์ ์ฌ์ฉํ์ฌ ์ฃผ์ธ ํ๋ ์ด๋ฆ์ ๊ฐ์ผ๋ก ์ ๋ ฅ
1. ๋ค๋์ผ(@ManyToOne)
๋ค๋์ผ ๋จ๋ฐฉํฅ [N:1]
ํ์ ์ํฐํฐ
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
ํ ์ํฐํฐ
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
}
- ํ์์ Member.team์ผ๋ก ํ ์ํฐํฐ๋ฅผ ์ฐธ์กฐ ๊ฐ๋ฅ
- ํ์ ํ์ ์ฐธ์กฐ ํ๋ ์์ด์ ์ฐธ์กฐ ๋ถ๊ฐ๋ฅ
- ๋ฐ๋ผ์ ํ์๊ณผ ํ์ ๋ค๋์ผ ๋จ๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ
- @JoinColumn(name = "TEAM_ID")๋ฅผ ์ฌ์ฉํด์ Member.team ํ๋๋ฅผ TEAM_ID FK์ ๋งคํ
๋ค๋์ผ ์๋ฐฉํฅ [N:1, 1:N]
์ค์ ์ด ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ(Member.team)์ด๊ณ ์ ์ (Team.members)์ ์ฃผ์ธ์ด ์๋๋ค.
ํ์ ์ํฐํฐ
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
public void setTeam(Team team) {
this.team = team;
// ๋ฌดํ๋ฃจํ์ ๋น ์ง์ง ์๋๋ก ์ฒดํฌ
if(!team.getMembers().contains(this)) {
team.getMembers().add(this)
}
}
}
ํ ์ํฐํฐ
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<Member>();
public void addMember(Member member) {
this.members.add(member);
// ๋ฌดํ๋ฃจํ์ ๋น ์ง์ง ์๋๋ก ์ฒดํฌ
if (member.getTeam() != this) {
member.setTeam(this);
}
}
}
- ์๋ฐฉํฅ์ FK๊ฐ ์๋ ์ชฝ์ด ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ
- 1:N, N:1 ๊ฒฝ์ฐ์ ํญ์ N์ FK๊ฐ ์์ผ๋ฏ๋ก N ์ชฝ์ด ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ
- JPA๋ FK๋ฅผ ๊ด๋ฆฌํ ๋ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ๋ง ์ฌ์ฉ
- ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ๋ ํญ์ ์๋ก๋ฅผ ์ฐธ์กฐํด์ผ ํจ
2. ์ผ๋๋ค(@OneToMany)
์ผ๋๋ค ๋จ๋ฐฉํฅ [1:N]
ํ ์ํฐํฐ
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany(mappedBy = "team")
@JoinColumn(name = "TEAM_ID") // MEMBER ํ
์ด๋ธ์ TEAM_ID (FK)
private List<Member> members = new ArrayList<Member>();
}
ํ์ ์ํฐํฐ
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
}
- 1:N ๊ด๊ณ์์ N ์ชฝ์ FK๊ฐ ์๊ธฐ ๋๋ฌธ์ ํ ์ํฐํฐ์ Team.members๋ก ํ์ ํ ์ด๋ธ์ TEAM_ID FK ๊ด๋ฆฌ
- ๋ฐ๋ผ์ 1์ชฝ์์ ๊ด๋ฆฌํ๋ FK๊ฐ N ์ชฝ์ ํ ์ด๋ธ์ ์๋ค๋ ๊ฒ์ด ๋จ์
- ์ด ๊ฒฝ์ฐ ์ํฐํฐ ์ ์ฅ๊ณผ ์ฐ๊ด๊ด๊ณ ์ฒ๋ฆฌ๋ฅผ ์ํด insert ์ด์ธ์ ์ถ๊ฐ๋ก update sql์ ์คํํด์ผ ํจ
- ๊ฒฐ๋ก => ์ผ๋๋ค ๋จ๋ฐฉํฅ๋ณด๋ค๋ ๋ค๋์ผ ์๋ฐฉํฅ ๋งคํ์ ์ฌ์ฉํ์!!!
์ผ๋๋ค ์๋ฐฉํฅ [1:N, N:1]
1:N, N:1 ๊ด๊ณ์์ ํญ์ N ์ชฝ์ FK๊ฐ ์๊ธฐ ๋๋ฌธ์ ์๋ฐฉํฅ ๋งคํ์์ @OneToMany๋ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ด ๋ ์ ์๋ค. ๋ฐ๋ผ์ ์ผ์ด ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ธ ์ผ๋๋ค ์๋ฐฉํฅ ๋งคํ์ ์กด์ฌํ์ง ์๋๋ค. ๋ค๋ง ์ผ๋๋ค ๋จ๋ฐฉํฅ ๋งคํ ๋ฐ๋ํธ์ ๋ค๋์ผ ๋จ๋ฐฉํฅ ๋งคํ์ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ถ๊ฐํด์ ์ผ๋๋ค ์๋ฐฉํฅ์ฒ๋ผ ๋ณด์ด๋๋ก ํ ์ ์๋ค. ํ์ง๋ง ์ด ๋ฐฉ๋ฒ๋ ์์์ ์ค๋ช ํ ์ผ๋๋ค ๋จ๋ฐฉํฅ ๋งคํ์ ๋จ์ ์ ๊ทธ๋๋ก ๊ฐ์ง๋ค.
ํ ์ํฐํฐ
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany(mappedBy = "team")
@JoinColumn(name = "TEAM_ID") // MEMBER ํ
์ด๋ธ์ TEAM_ID (FK)
private List<Member> members = new ArrayList<Member>();
}
ํ์ ์ํฐํฐ
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID", insertable = false, updatable = false) // ์ฝ๊ธฐ ์ ์ฉ
private Team team;
}
3. ์ผ๋์ผ [1:1]
์ฃผ ํ ์ด๋ธ์ FK
- ์ฃผ ํ ์ด๋ธ์ FK๋ฅผ ๋๊ณ ๋์ ํ ์ด๋ธ ์ฐธ์กฐ
- FK๋ฅผ ๊ฐ์ฒด ์ฐธ์กฐ์ ๋น์ทํ๊ฒ ์ฌ์ฉํ ์ ์์
- ์ฃผ ํ ์ด๋ธ๋ง ํ์ธํด๋ ๋์ ํ ์ด๋ธ๊ณผ ์ฐ๊ด๊ด๊ณ๊ฐ ์๋์ง ํ์ธ ๊ฐ๋ฅ
๋จ๋ฐฉํฅ
ํ์ MEMBER๊ฐ ์ฃผ ํ ์ด๋ธ์ด๊ณ ์ฌ๋ฌผํจ LOCKER๊ฐ ๋์ ํ ์ด๋ธ์ธ ์์
ํ์, ์ฌ๋ฌผํจ ์ํฐํฐ
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@OneToOne
@JoinColumn(name = "LOCKER_ID")
private Locker locker;
}
@Entity
public class Locker {
@Id @GeneratedValue
@Column(name = "LOCKER_ID")
private Long id;
private String name;
}
์๋ฐฉํฅ
MEMBER ํ ์ด๋ธ์ด FK๋ก LOCKER_ID๋ฅผ ๊ฐ์ง๋ค๊ณ ๊ฐ์ ํ๋ค.
ํ์, ์ฌ๋ฌผํจ ์ํฐํฐ
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@OneToOne
@JoinColumn(name = "LOCKER_ID")
private Locker locker;
}
@Entity
public class Locker {
@Id @GeneratedValue
@Column(name = "LOCKER_ID")
private Long id;
private String name;
@OneToOne(mappedBy = "locker")
private Member member;
}
- MEMBER ํ ์ด๋ธ์ด FK๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก Member.locker๊ฐ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ
- ๋ฐ๋ผ์ Locker.member๋ mappedBy๋ฅผ ์ ์ธํด์ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ด ์๋๋ผ๊ณ ์ค์
๋์ ํ ์ด๋ธ์ FK
- ํ ์ด๋ธ ๊ด๊ณ๋ฅผ 1:1์์ 1:N์ผ๋ก ์ฝ๊ฒ ๋ณ๊ฒฝ ๊ฐ๋ฅ
๋จ๋ฐฉํฅ
1:1 ๊ด๊ณ์์ ๋์ ํ ์ด๋ธ์ FK๊ฐ ์๋ ๋จ๋ฐฉํฅ ๊ด๊ณ๋ JPA์์ ์ง์ํ์ง ์๋๋ค.
์๋ฐฉํฅ
ํ์ MEMBER๊ฐ ์ฃผ ํ ์ด๋ธ์ด๊ณ ์ฌ๋ฌผํจ LOCKER๊ฐ ๋์ ํ ์ด๋ธ์ธ ์์
ํ์, ์ฌ๋ฌผํจ ์ํฐํฐ
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@OneToOne(mappedBy = "member")
private Locker locker;
}
@Entity
public class Locker {
@Id @GeneratedValue
@Column(name = "LOCKER_ID")
private Long id;
private String name;
@OneToOne
@JoinColumn(name = "MEMBER_ID")
private Member member;
}
4. ๋ค๋๋ค [N:N]
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ ๊ทํ๋ ํ ์ด๋ธ 2๊ฐ๋ก ๋ค๋๋ค ๊ด๊ณ๋ฅผ ํํํ ์ ์๋ค. ๊ทธ๋์ ๋ณดํต ๋ค๋๋ค ๊ด๊ณ๋ฅผ ์ผ๋๋ค, ๋ค๋์ผ ๊ด๊ณ๋ก ํ์ด๋ด๋ ์ฐ๊ฒฐ ํ ์ด๋ธ์ ์ฌ์ฉํ๋ค.
์์๋ก ํ์๊ณผ ์ํ ํ ์ด๋ธ์ ์๊ฐํด๋ณด๋ฉด, ํ์๋ค์ ์ฌ๋ฌ ์ํ์ ์ฃผ๋ฌธํ ์ ์๊ณ ์ํ๋ค์ ์ฌ๋ฌ ํ์์ ์ํด ์ฃผ๋ฌธ๋ ์ ์๋ ๋ค๋๋ค ๊ด๊ณ์ด๋ค. ์ด ๊ฒฝ์ฐ ํ์ ํ ์ด๋ธ๊ณผ ์ํ ํ ์ด๋ธ๋ง์ผ๋ก ์ด ๊ด๊ณ๋ฅผ ํํํ ์ ์๊ณ Member_Product์ ๊ฐ์ ์ฐ๊ฒฐ ํ ์ด๋ธ์ ์ด์ฉํด ๊ด๊ณ๋ฅผ ํํํด์ผ ํ๋ค.
ํ์ง๋ง ๊ฐ์ฒด๋ ํ ์ด๋ธ๊ณผ ๋ค๋ฅด๊ฒ ๊ฐ์ฒด 2๊ฐ๋ก ๋ค๋๋ค ๊ด๊ณ๋ฅผ ๋ง๋ค ์ ์๋ค. @ManyToMany๋ฅผ ์ด์ฉํ์ฌ ๋ค์ ๊ทธ๋ฆผ์ฒ๋ผ ๋ค๋๋ค ๊ด๊ณ๋ฅผ ๋งคํํ ์ ์๋ค.
๋จ๋ฐฉํฅ
ํ์, ์ํ ์ํฐํฐ
@Entity
public class Member {
@Id
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@ManyToMany
@JoinTable(name = "MEMBER_PRODUCT",
joinColumns = @JoinColumn(name = "MEMBER_ID"),
inverseJoinColumns = @JoinColumn(name = "PRODUCT_ID"))
private List<Product> products = new ArrayList<Product>();
}
@Entity
public class Product {
@Id
@Column(name = "PRODUCT_ID")
private Long id;
private String name;
}
์๋ฐฉํฅ
ํ์ ์ํฐํฐ์ addProduct, ์ํ ์ํฐํฐ์ ์ญ๋ฐฉํฅ ๋งคํ ์ถ๊ฐ
@Entity
public class Member {
@Id
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@ManyToMany
@JoinTable(name = "MEMBER_PRODUCT",
joinColumns = @JoinColumn(name = "MEMBER_ID"),
inverseJoinColumns = @JoinColumn(name = "PRODUCT_ID"))
private List<Product> products = new ArrayList<Product>();
public void addProduct(Product product) {
// ์๋ต
products.add(product);
product.getMembers().add(this);
}
}
@Entity
public class Product {
@Id
@Column(name = "PRODUCT_ID")
private Long id;
private String name;
@ManyToMany(mappedBy = "products")
private List<Member> members;
}
@ManyToMany๋ฅผ ์ฌ์ฉํด์ ์ฐ๊ฒฐ ํ ์ด๋ธ์ ์ฒ๋ฆฌํ ๊ฒฝ์ฐ ์ฐ๊ฒฐ ํ ์ด๋ธ์ ์ปฌ๋ผ์ ์ถ๊ฐํ ์ ์๋ค. ๋ฐ๋ผ์ ์ด ๊ฒฝ์ฐ์๋ ์ฐ๊ฒฐ ์ํฐํฐ๋ฅผ ๋ง๋ค๊ณ ์ด๊ณณ์ ์ถ๊ฐํ ์ปฌ๋ผ๋ค์ ๋งคํํด์ผ ํ๋ค.
์๋ฅผ ๋ค์ด, Member_Product ํ ์ด๋ธ์ ์ฃผ๋ฌธ ์๋๊ณผ ์ฃผ๋ฌธ ๋ ์ง ์ปฌ๋ผ์ ์ถ๊ฐํด์ผ ํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ฐ๊ด๊ด๊ณ๋ฅผ ์ค์ ํ ์ ์๋ค. ์ด ๊ฒฝ์ฐ MemberProduct ์ํฐํฐ๋ (MEMBER_ID, PRODUCT_ID)๋ฅผ ๋ณตํฉํค๋ก ๊ฐ์ง๊ฒ ๋๋ค.
์ฐธ๊ณ : ์๋ฐ ORM ํ์ค JPA ํ๋ก๊ทธ๋๋ฐ(์ง์์ด: ๊น์ํ)