π[Spring] μλ°©ν₯ κ΄κ³λ 무μμΌκΉμ?
-
μλ°©ν₯ κ΄κ³λ λ μν°ν°κ° μλ‘λ₯Ό μ°Έμ‘°ν μ μλ κ΄κ³λ₯Ό μλ―Έν©λλ€.
- μ¦, ν μν°ν°μμ λ€λ₯Έ μν°ν°λ₯Ό μ°Έμ‘°ν μ μμ λΏλ§ μλλΌ, λ°λλ‘ λ€λ₯Έ μν°ν°μμλ μ΄λ₯Ό μ°Έμ‘°ν μ μμ΅λλ€.
- μλ°©ν₯ κ΄κ³λ₯Ό μ¬μ©νλ©΄ λ μν°ν° κ°μ λ°μ΄ν° νμμ΄ μμͺ½ λ°©ν₯μΌλ‘ λͺ¨λ κ°λ₯ν΄μ§λ©°, μ΄λ JPAμμ λ€μκ³Ό κ°μ κ΄κ³ μ΄λ
Έν
μ΄μ
μ‘°ν©μΌλ‘ ꡬνλ©λλ€.
-
@OneToMany
+@ManyToOne
-
@OneToOne
+@OneToOne
-
@ManyToMany
+@ManyToMany
-
1οΈβ£ μλ°©ν₯ κ΄κ³μ νΉμ§.
1οΈβ£ μμͺ½μμ μ°Έμ‘° κ°λ₯.
- μμͺ½ μν°ν°κ° μλ‘λ₯Ό μ°Έμ‘°νμ¬ λ°μ΄ν° νμμ΄ κ°λ₯ν©λλ€.
- μλ₯Ό λ€μ΄, λΆλͺ¨ μν°ν°μμ μμ μν°ν°λ€μ μ‘°ννκ±°λ, μμ μν°ν°μμ λΆλͺ¨ μν°ν°λ₯Ό μ‘°νν μ μμ΅λλ€.
2οΈβ£ μ£ΌμΈ(Owner)κ³Ό λΉμ£ΌμΈ(Inverse) μ€μ .
- JPAμμ μλ°©ν₯ κ΄κ³λ₯Ό μ€μ ν λ, λ°λμ μ£ΌμΈ(Owner)κ³Ό λΉμ£ΌμΈ(Inverse)μ λͺ μν΄μΌ ν©λλ€.
- μ£ΌμΈ(Owner) : μΈλ ν€(Foreign Key)λ₯Ό μ€μ λ‘ κ΄λ¦¬νλ μͺ½.
-
λΉμ£ΌμΈ(Inverse) : μ½κΈ° μ μ©μΌλ‘ μ°Έμ‘°λ§ κ°λ₯νλ©°,
mappedBy
μμ±μ ν΅ν΄ μ£ΌμΈμ λͺ μν©λλ€.
3οΈβ£ λ°μ΄ν°λ² μ΄μ€μμ μΈλ ν€λ νμͺ½μλ§ μ‘΄μ¬.
- λ°μ΄ν°λ² μ΄μ€μ μΈλ ν€(Foreign Key)λ κ΄κ³μ μ£ΌμΈμ ν΄λΉνλ μν°ν°μ ν μ΄λΈμλ§ μ‘΄μ¬ν©λλ€.
2οΈβ£ μλ°©ν₯ κ΄κ³μ ꡬν νν.
1οΈβ£ @OneToMany
+ @ManyToOne
- λΆλͺ¨-μμ κ΄κ³λ₯Ό ꡬννλ©°, λΆλͺ¨λ μμμ 컬λ μ μ κ°μ§κ³ μκ³ , μμμ λΆλͺ¨λ₯Ό μ°Έμ‘°ν©λλ€.
μμ : Userμ UserSaveHistory
- User μν°ν°(λΆλͺ¨)
@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private List<UserSaveHistory> saveHistories = new ArrayList<>(); public void addSaveHistory(UserSaveHistory history) { saveHistories.add(history); history.setUser(this); } public void removeSaveHistory(UserSaveHistory history) { saveHistories.remove(history); history.setUser(null); } }
- UserSaveHistory μν°ν°(μμ)
@Entity public class UserSaveHistory { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User user; }
2οΈβ£ @OneToOne
+ @OneToOne
- 1:1 κ΄κ³λ₯Ό ꡬννλ©°, μμͺ½ μν°ν°κ° μλ‘λ₯Ό μ°Έμ‘°ν©λλ€.
μμ : Passportμ Person
- Person μν°ν°.
@Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @OneToOne(mappedBy = "person", cascade = CascadeType.ALL) private Passport passport; }
- Passport μν°ν°.
@Entity public class Passport { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @OneToOne @JoinColumn(name = "person_id") private Person person; }
3οΈβ£ @ManyToMany
+ @ManyToMany
- λ€λλ€ κ΄κ³λ₯Ό ꡬννλ©°, μ€κ° ν μ΄λΈμ ν΅ν΄ λ μν°ν°κ° μ°κ²°λ©λλ€.
μμ : Studentμ Course
- Student μν°ν°.
@Entity public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToMany @JoinTable( name = "student_course", joinColumns = @JoinColumn(name = "student_id"), inverseJoinColumns = @JoinColumn(name = "course_id") ) private List<Course> courses = new ArrayList<>(); }
- Course μν°ν°.
@Entity public class Course { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToMany(mappedBy = "courses") private List<Student> students = new ArrayList<>(); }
3οΈβ£ μλ°©ν₯ κ΄κ³μμ μ£Όμμ .
1οΈβ£ μ£ΌμΈ(Owner)κ³Ό λΉμ£ΌμΈ(Inverse)
- JPAμμλ μλ°©ν₯ κ΄κ³λ₯Ό μ€μ ν λ λ°λμ μ£ΌμΈμ λͺ μν΄μΌ ν©λλ€.
- μ£ΌμΈμ μΈλ ν€(Foreign Key)λ₯Ό κ΄λ¦¬νλ©°, λ°μ΄ν° λ³κ²½(INSERT, UPDATE)μ μν₯μ λ―ΈμΉ©λλ€.
-
λΉμ£ΌμΈμ
mappedBy
μμ±μ μ¬μ©ν΄ μ£ΌμΈμ μ§μ νλ©°, μ½κΈ° μ μ©μ λλ€.
2οΈβ£ μ°κ΄ κ΄κ³ νΈμ λ©μλ.
- λΆλͺ¨μ μμ κ°μ κ΄κ³λ₯Ό μΌκ΄λκ² μ μ§νλ €λ©΄ νΈμ λ©μλλ₯Ό μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.
- μλ₯Ό λ€μ΄, λΆλͺ¨μ
addChild
λ©μλλ₯Ό νΈμΆνλ©΄ μμμ λΆλͺ¨λ μλμΌλ‘ μ€μ λλλ‘ κ΅¬νν©λλ€.public void addSaveHistory(UserSaveHistory history) { saveHistories.add(history); history.setUser(this); }
- μλ₯Ό λ€μ΄, λΆλͺ¨μ
πββοΈ νΈμ λ©μλ
κ΄κ³λ₯Ό λκΈ°ννκΈ° μν νΈμ λ©μλλ μλ°©ν₯ μ°κ΄ κ΄κ³μμ λ μν°ν° κ°μ μ°κ΄ κ΄κ³λ₯Ό μΌκ΄μ± μκ² μ μ§νκΈ° μν΄ μ¬μ©νλ λ©μλλ₯Ό μλ―Έν©λλ€.
3οΈβ£ μ§μ° λ‘λ©(Lazy Loading)
- μλ°©ν₯ κ΄κ³μμλ
@OneToMany
μ@ManyToOne
λͺ¨λ κΈ°λ³Έμ μΌλ‘ μ§μ° λ‘λ©(Lazy Loading)μ μ¬μ©νμ¬ μ±λ₯μ μ΅μ νν©λλ€. - νμμ
fetch = FetchType.EAGER
λ‘ μ€μ ν μ μμ§λ§, μ΄λ λ°μ΄ν° λ‘λ© μ μ±λ₯μ μν₯μ μ€ μ μμ΅λλ€.
4οΈβ£ 무ν 루ν λ¬Έμ
- μλ°©ν₯ κ΄κ³λ₯Ό JSONμΌλ‘ μ§λ ¬νν λ, λΆλͺ¨μ μμμ΄ μλ‘λ₯Ό μ°Έμ‘°νλ©° 무ν 루νκ° λ°μν μ μμ΅λλ€.
- ν΄κ²° λ°©λ²
-
@JsonIgnore
: νΉμ νλλ₯Ό μ§λ ¬ννμ§ μλλ‘ μ€μ . -
@JsonManagedReference
μ@JsonBackReference
: Jackson λΌμ΄λΈλ¬λ¦¬μμ κ΄κ³λ₯Ό μ²λ¦¬νλ μ΄λ Έν μ΄μ .
-
- ν΄κ²° λ°©λ²
4οΈβ£ μ₯μ κ³Ό λ¨μ .
1οΈβ£ μ₯μ .
1οΈβ£ μμͺ½ νμ κΈ°λ₯.
- λΆλͺ¨μ μμ λͺ¨λμμ κ΄κ³λ₯Ό νμν μ μμ΅λλ€.
2οΈβ£ λͺ νν κ΄κ³ νν.
- κ°μ²΄ λͺ¨λΈμμ λ μν°ν° κ°μ κ΄κ³λ₯Ό λͺ ννκ² ννν μ μμ΅λλ€.
2οΈβ£ λ¨μ .
1οΈβ£ μ€κ³ 볡μ‘μ± μ¦κ°.
- κ΄κ³λ₯Ό μμͺ½μμ κ΄λ¦¬ν΄μΌ νλ―λ‘ μ½λκ° λ³΅μ‘ν΄μ§ μ μμ΅λλ€.
2οΈβ£ μ±λ₯ λ¬Έμ .
- μλ°©ν₯ κ΄κ³λ₯Ό μ¬μ©ν κ²½μ° λΆνμν λ°μ΄ν° λ‘λ©μ΄ λ°μν μ μμΌλ―λ‘ λ‘λ© μ λ΅μ μ μ€ν μ νν΄μΌ ν©λλ€.
5οΈβ£ κ²°λ‘ .
- μλ°©ν₯ κ΄κ³λ λ μν°ν° κ°μ μνΈ μ°Έμ‘°κ° νμν λ μ¬μ©λλ©°, μ€κ³κ° 볡μ‘ν΄μ§ μ μμ§λ§ λ°μ΄ν°λ₯Ό μμͺ½ λ°©ν₯μΌλ‘ νμν΄μΌ νλ κ²½μ° μ μ©ν©λλ€.
- JPAμμλ μ£ΌμΈ(Owner)μ λͺ νν μ€μ νκ³ , νΈμ λ©μλλ₯Ό ν΅ν΄ κ΄κ³λ₯Ό κ΄λ¦¬ν¨μΌλ‘μ¨ λ°μ΄ν°μ μΌκ΄μ±μ μ μ§ν΄μΌ ν©λλ€.
- νμ μλ κ²½μ° λ¨λ°©ν₯ κ΄κ³λ₯Ό μ¬μ©νλ κ²μ΄ λ κ°λ¨νκ³ μ±λ₯μ μ 리ν©λλ€.