Backend Ddevelopment
โ๐[Backend Development] @OneToMany๋ ๋ฌด์์ผ๊น์?โ
๐ Intro.
- @OneToMany๋ ์ผ๋๋ค(1:N) ๊ด๊ณ๋ฅผ ๋งคํํ ๋ ์ฌ์ฉํ๋ ์ด๋
ธํ
์ด์
์
๋๋ค.
- ์ฆ, ํ๋(One)์ ์ํฐํฐ๊ฐ ์ฌ๋ฌ ๊ฐ(Many)์ ์ํฐํฐ๋ฅผ ์ฐธ์กฐํ๋ ๊ตฌ์กฐ์
๋๋ค.
โ
1๏ธโฃ @OneToMany ์์ .
- ๊ฒ์๊ธ(Article)๊ณผ ๋๊ธ(Comment) ๊ด๊ณ๋ฅผ ์๋ก ๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
- ํ๋์ ๊ฒ์๊ธ(Article)์๋ ์ฌ๋ฌ ๊ฐ์ ๋๊ธ(Comment)์ด ๋ฌ๋ฆด ์ ์์ต๋๋ค.
1๏ธโฃ Article ์ํฐํฐ(๊ฒ์๊ธ)
@Entity
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String content;
@OneToMany(mappedBy = "article") // Comment ์ํฐํฐ์ article ํ๋๊ฐ ๊ด๊ณ์ ์ฃผ์ธ
private List<Comment> comments = new ArrayList<>();
// Getter, Setter
}
@Entity
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String content;
@ManyToOne
@JoinColumn(name = "article_id") // comment ํ
์ด๋ธ์ article_id FK ์์ฑ
private Article article;
// Getter, Setter
}
โ
2๏ธโฃ @OneToMany(mappedBy = โarticleโ)์ ์๋ฏธ
- Comment ์ํฐํฐ์ article ํ๋๋ฅผ ์ฐธ์กฐํ์ฌ ์๋ฐฉํฅ ๊ด๊ณ๋ฅผ ์ค์ ํฉ๋๋ค.
-
์ธ๋ ํค๋ฅผ ๊ด๋ฆฌํ๋ ์ฃผ์ธ์ Comment.article ํ๋์ด๋ฉฐ, Article ์ํฐํฐ๋ mappedBy๋ฅผ ํตํด ์ฝ๊ธฐ ์ ์ฉ์
๋๋ค.
- ์ฆ, Comment ์ํฐํฐ๊ฐ ๊ด๊ณ์ ์ฃผ์ธ์ด๊ณ , Article ์ํฐํฐ์์๋ ์ง์ FK๋ฅผ ๊ด๋ฆฌํ์ง ์์ต๋๋ค. (โ @JoinColumn์ด Comment ์ชฝ์๋ง ์๋ ์ด์ )
โ
3๏ธโฃ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ
์ด๋ธ ๊ตฌ์กฐ.
- ์ ์ฝ๋๋ฅผ ์คํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ํ
์ด๋ธ์ด ์์ฑ๋ฉ๋๋ค.
๐ article ํ
์ด๋ธ (๊ฒ์๊ธ)
id |
title |
content |
1 |
โHello JPAโ |
โJPA ๋ฐฐ์ฐ๊ธฐโ |
2 |
โSpring Bootโ |
โSpring ๊ณต๋ถโ |
๐ comment ํ
์ด๋ธ (๊ฒ์๊ธ์ ์ฐ๊ฒฐ๋ ๋๊ธ, article_id FK ํฌํจ)
id |
content |
article_id(FK) |
1 |
โ์ข์ ๊ธ์ด๋ค์!โ |
1 |
2 |
โ์ ์ตํ ์ ๋ณด ๊ฐ์ฌํฉ๋๋ค.โ |
1 |
3 |
โSpring ์ต๊ณ !โ |
2 |
- ๐ article_id ์ปฌ๋ผ์ด ๊ฒ์๊ธ(Article)์ ์ฐธ์กฐํ๋ ์ธ๋ ํค(FK)์
๋๋ค.
- ์ฆ, ํ๋์ Article์๋ ์ฌ๋ฌ ๊ฐ์ Comment๊ฐ ์ฐ๊ฒฐ๋ ์ ์์ต๋๋ค.
โ
4๏ธโฃ ๋ฐ์ดํฐ ์กฐํ.
โ
ํน์ ๊ฒ์๊ธ์ ์ํ ๋๊ธ ๊ฐ์ ธ์ค๊ธฐ.
- ์๋ฐฉํฅ ๊ด๊ณ๊ฐ ์ค์ ๋์ด ์์ผ๋ฏ๋ก, ํน์ ๊ฒ์๊ธ์ ๋ฌ๋ฆฐ ๋๊ธ์ ์ฝ๊ฒ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
Article article = entityManager.find(Article.class, 1L);
List<Comment> comments = article.getComments(); // ํด๋น ๊ฒ์๊ธ์ ๋ชจ๋ ๋๊ธ ๊ฐ์ ธ์ค๊ธฐ
๐5๏ธโฃ ๋จ๋ฐฉํฅ @OneToMany vs ์๋ฐฉํฅ @OneToMany
1๏ธโฃ ๋จ๋ฐฉํฅ @OneToMany
@Entity
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String content;
@OneToMany
@JoinColumn(name = "article_id") // FK๋ฅผ ์ง์ ๊ด๋ฆฌ (์ฃผ์ธ ์ญํ )
private List<Comment> comments = new ArrayList<>();
// Getter, Setter
}
โ
์ฅ์ .
- ๋จ์ํ ๊ตฌ์กฐ.
- ๋ถํ์ํ mappedBy ์์ด @JoinColumn์ ํตํด FK ์ง์ ๊ด๋ฆฌ ๊ฐ๋ฅ
โ ๋จ์ .
- ๋ฐ์ดํฐ ์ฝ์
์ ์ถ๊ฐ์ ์ธ SQL ์คํ ๋ฐ์
- @OneToMany ๋จ๋ฐฉํฅ ๊ด๊ณ์์ @JoinColumn์ ์ฌ์ฉํ๋ฉด INSERT ์ฟผ๋ฆฌ๊ฐ ๋ ๋ฒ ์คํ๋จ (โ ๋๊ธ ์ฝ์
ํ, ๊ฒ์๊ธ ID ์
๋ฐ์ดํธ)
2๏ธโฃ ์๋ฐฉํฅ @OneToMany + @ManyToOne
@Entity
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String content;
@OneToMany(mappedBy = "article") // Comment์ article ํ๋๋ฅผ ์ฃผ์ธ์ผ๋ก ์ค์
private List<Comment> comments = new ArrayList<>();
// Getter, Setter
}
โ
์ฅ์ .
- ์ฑ๋ฅ ์ต์ ํ ๊ฐ๋ฅ (FK๋ Comment.article์ด ๊ด๋ฆฌ).
- INSERT ์ฟผ๋ฆฌ ์คํ์ด ํ ๋ฒ๋ง ๋ฐ์.
- ๊ฐ์ฒด ๊ทธ๋ํ ํ์์ด ํธ๋ฆฌํจ (article.getComments() ๊ฐ๋ฅ).
โ ๋จ์
- mappedBy๋ก ์ธํด ๋ฐ์ดํฐ ์ ์ฅ์ด Comment ์ชฝ์์ ์ด๋ฃจ์ด์ ธ์ผ ํจ.
โ
6๏ธโฃ ์ ๋ฆฌ
- โ๏ธ @OneToMany๋ ํ๋(One)์ ์ํฐํฐ๊ฐ ์ฌ๋ฌ ๊ฐ(Many)์ ์ํฐํฐ๋ฅผ ์ฐธ์กฐํ ๋ ์ฌ์ฉ.
- โ๏ธ ์๋ฐฉํฅ ๊ด๊ณ์์๋ @OneToMany(mappedBy = โํ๋๋ช
โ) + @ManyToOne ์กฐํฉ ์ฌ์ฉ
- โ๏ธ ๋จ๋ฐฉํฅ @OneToMany๋ณด๋ค๋ ์๋ฐฉํฅ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์
- โ๏ธ ์ธ๋ ํค(FK)๋ @ManyToOne ์ชฝ์์ ๊ด๋ฆฌํ๋ฉฐ, @OneToMany๋ ์ฝ๊ธฐ ์ ์ฉ
- ๐ ๊ฒ์๊ธ-๋๊ธ ๊ด๊ณ์ฒ๋ผ 1:N ๊ด๊ณ๊ฐ ํ์ํ ๋ @OneToMany๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.