Home
>
Spring
>
๐[Spring] JPA ์ฐ๊ด๊ด๊ณ์ ๋ํ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ๋ค์๋ ๋ฌด์์ด ์์๊น์? - ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ ํจ๊ณผ
Spring
Framework
๐[Spring] JPA ์ฐ๊ด๊ด๊ณ์ ๋ํ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ๋ค์๋ ๋ฌด์์ด ์์๊น์? - ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ ํจ๊ณผ
1๏ธโฃ ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ ํจ๊ณผ.
- JPA์์ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ผ๋ก ์ค์ ๋ ์ํฐํฐ๋ง ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ธ๋ ํค๋ฅผ ๋ฐ์ํ ์ ์๋ ํจ๊ณผ๋ฅผ ๋งํฉ๋๋ค.
- JPA์์๋ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ(Owner)๊ณผ ์ฃผ์ธ์ด ์๋ ์ํฐํฐ(Non-owner)๋ฅผ ๊ตฌ๋ถํ์ฌ, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ธ๋ ํค๋ฅผ ์ ์ฅํ๊ฑฐ๋ ์
๋ฐ์ดํธํ ๋ ์ฃผ์ธ์ผ๋ก ์ค์ ๋ ์ํฐํฐ๋ง ์ค์ SQL์ ๋ฐ์๋๋๋ก ํฉ๋๋ค.
2๏ธโฃ ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ ํจ๊ณผ์ ๋์ ๋ฐฉ์.
- ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ์์ ๋ ์ํฐํฐ๊ฐ ์๋ก๋ฅผ ์ฐธ์กฐํ ๋, ์ด๋ ํ์ชฝ์ โ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธโ์ผ๋ก ์ค์ ํ๊ณ , ๊ทธ ์ฃผ์ธ์์๋ง ์ธ๋ ํค ๊ฐ์ ์ ์ฅํ๊ฑฐ๋ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
- ์ฃผ์ธ์ด ์๋ ์ชฝ์์๋ mappedBy ์์ฑ์ ํตํด ์ฃผ์ธ์ด ์๋์ ๋ช
์ํ๊ณ , ์ด๋ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ทจ๊ธ๋ฉ๋๋ค.
- ์ด๋ฅผ ํตํด JPA๋ ์ค๋ณต๋ ์ธ๋ ํค ์ ์ฅ์ ๋ฐฉ์งํ๊ณ , ์ค์ ์ธ๋ ํค ๊ด๋ฆฌ๋ฅผ ์ผ๊ด๋๊ฒ ์ฒ๋ฆฌํฉ๋๋ค.
๐ ์์: 1:1 ๊ด๊ณ์์์ ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ ํจ๊ณผ.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne
@JoinColumn(name = "user_profile_id") // ์ธ๋ ํค ๊ด๋ฆฌ
private UserProfile userProfile;
// getter, setter ๋ฑ
}
@Entity
public class UserProfile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String address;
private String phoneNumber;
@OneToOne(mappedBy = "userProfile") // ์ฃผ์ธ์ด ์๋์ ๋ช
์
private User user;
// getter, setter ๋ฑ
}
- ์ ์ฝ๋์์ User ์ํฐํฐ๊ฐ UserProfile ์ํฐํฐ์ ์ฐ๊ด๊ด๊ณ์์ ์ฃผ์ธ์
๋๋ค.
- userProfile ํ๋์ ๋ํ ์ค์ ๋ง ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์๋ฉ๋๋ค.
๐ ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ ํจ๊ณผ์ ์์ ์ํฉ.
User user = new User();
UserProfile profile = new UserProfile();
user.setUserProfile(profile);
profile.setUser(user);
entityManager.persist(user);
entityManager.persist(profile);
- ์์ ๊ฐ์ด user์ userProfile์ ์ค์ ํ๊ณ profile์ user๋ฅผ ์ค์ ํด๋, ์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์๋ User ์ํฐํฐ์ userProfile์ ์ค์ ๋ ๊ฐ๋ง ์ธ๋ ํค๋ก ๋ฐ์๋ฉ๋๋ค.
- UserProfile ์ํฐํฐ์์ user ํ๋์ ๋ณ๊ฒฝ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์๋์ง ์์ต๋๋ค.
- ์ด๋ฅผ ํตํด ๋ถํ์ํ ์ฟผ๋ฆฌ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ๋ฐฉ์งํ๊ณ , ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ์ ์งํ ์ ์์ต๋๋ค.
3๏ธโฃ ์์ฝ.
-
์ฐ๊ด๊ด๊ณ ์ฃผ์ธ๋ง ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ธ๋ ํค ์ ๋ณด๋ฅผ ๋ฐ์ํ ์ ์์ต๋๋ค.
-
์ฃผ์ธ์ด ์๋ ์ํฐํฐ์์ ์ค์ ํ ์ฐ๊ด๊ด๊ณ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์๋์ง ์์ผ๋ฉฐ, ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.
- ์ด๋ฅผ ํตํด ์ค๋ณต๋ ์ธ๋ ํค ์ ์ฅ์ ๋ฐฉ์งํ๊ณ , ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ์ ์งํ ์ ์์ต๋๋ค.
4๏ธโฃ ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ.
-
์ธ๋ ํค(Foreign Key)๋ฅผ ๊ด๋ฆฌํ๋ ์ํฐํฐ๋ฅผ ๋งํฉ๋๋ค.
- ์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ด๊ด๊ณ์ ๊ด๋ จ๋ ๋ณ๊ฒฝ์ฌํญ์ ๋ฐ์ํ ๋ ์ด๋ค ์ํฐํฐ๊ฐ ์ธ๋ ํค์ ์์ , ์ฝ์
, ์ญ์ ์์
์ ์ํํ๋์ง๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
5๏ธโฃ ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ์ ์ญํ .
- ์ฐ๊ด๊ด๊ณ์์ ์ฃผ์ธ์ผ๋ก ์ง์ ๋ ์ํฐํฐ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ธ๋ ํค ์ปฌ๋ผ์ ๊ด๋ฆฌํ๋ฉฐ, ์ฃผ์ธ์ด ์๋ ์ชฝ์์๋ ์ฐ๊ด๊ด๊ณ๋ฅผ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ฌ์ฉํฉ๋๋ค.
- ์๋ฅผ ๋ค์ด, ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ์์
@OneToOne
, @OneToMany
, @ManyToMany
, @ManyToOne
, @ManyToMany
์ค ์ฃผ์ธ์ด ๋๋ ์ชฝ์์๋ง ์ธ๋ ํค์ ๊ฐ์ด ๋ณ๊ฒฝ๋ฉ๋๋ค.
6๏ธโฃ ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ ์ค์ ์ ์ค์์ฑ.
- JPA์์ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ ์ค์ ํ๋ ์ด์ ๋ ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ์์ ๋ ์ํฐํฐ ๋ชจ๋ ์ฐ๊ด๊ด๊ณ๋ฅผ ๋งบ๊ณ ์๋ ๊ฒฝ์ฐ, ์ด๋ ์ชฝ์ด ์ค์ ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ํ ์ง๋ฅผ ๋ช
ํํ ํ๊ธฐ ์ํจ์
๋๋ค.
- ์ฃผ์ธ์ด ์๋ ์ํฐํฐ์์ ์ฐ๊ด๊ด๊ณ๋ฅผ ์ค์ ํ๋๋ผ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์๋ ๋ฐ์๋์ง ์๊ณ , ์ฃผ์ธ์์ ์ค์ ๋ ๋ด์ฉ๋ง ๋ฐ์๋ฉ๋๋ค.
๐ ์์ : 1:1 ๊ด๊ณ์์์ ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ ์ค์ .
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne
@JoinColumn(name = "user_profile_id") // ์ธ๋ ํค ๊ด๋ฆฌ
private UserProfile userProfile;
// getter, setter ๋ฑ
}
@Entity
public class UserProfile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String address;
private String phoneNumber;
@OneToOne(mappedBy = "userProfile") // ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ์ด ์๋์ ๋ช
์
private User user;
// getter, setter ๋ฑ
}
- ์ ์ฝ๋์์ User ์ํฐํฐ๊ฐ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ด๋ฉฐ, UserProfile์ mappedBy ์์ฑ์ ํตํด ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ์ด ์๋์ ๋ช
์ํ๊ณ ์์ต๋๋ค.
- ์ด ๊ฒฝ์ฐ ์ธ๋ ํค๋ User ์ํฐํฐ์ user_profile_id ์ปฌ๋ผ์ ์ ์ฅ๋ฉ๋๋ค.
7๏ธโฃ ์์ฝ.
-
์ฐ๊ด๊ด๊ณ ์ฃผ์ธ : ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ธ๋ ํค๋ฅผ ๊ด๋ฆฌํ๋ ์ํฐํฐ.
@JoinColumn
์ ํตํด ์ค์ ๋จ.
-
์ฃผ์ธ์ด ์๋ ์ํฐํฐ : mappedBy ์์ฑ์ ํตํด ์ค์ ๋๋ฉฐ, ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์๋.
- ์ฃผ์ธ๋ง์ด ์ธ๋ ํค ์์ , ์ญ์ , ์ฝ์
์ ๊ด๋ฆฌํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ํจ.