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λ₯Ό μ¬μ©νλ©΄ λ©λλ€.