Entity ์ฐ๊ด๊ด๊ณ
- 1:1
- N:1
- 1:N
- N:M
์ค์ ๋ก ํ ์ด๋ธ์ ๋ฑ ํ๊ฐ๋ง ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ ๊ฑฐ์ ์๋ค.
DB table์ ์ฐ๊ด๊ด๊ณ Entity ๊ฐ์ฒด์ ์ฐ๊ด๊ด๊ณ ์ฐจ์ด๊ฐ ์์๊น? ์๋ค๋ฉด ์ด๋ป๊ฒ ๋ค๋ฅผ๊น?
์๋ฅผ ๋ค์ด, ๊ณ ๊ฐ์ด ์์์ ์ฃผ๋ฌธํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ๋ค๊ณ ๊ฐ์ ํด๋ณด์.
๊ทธ๋ ๋ค๋ฉด ๋น์ฐํ ์ฃผ๋ฌธํ๋ ๊ณ ๊ฐ ํ ์ด๋ธ ํ๋, ์์ ํ ์ด๋ธ ํ๋ ์ด ๋๊ฐ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ํ ๊ฒ์ด๋ค.
๊ทธ๋ฐ๋ฐ ๊ณ ๊ฐ์ด ์์์ ์ฃผ๋ฌธํ์ ๋ ํด๋น ์ฃผ๋ฌธ๊ฑด์ ๋ํ๊ฑด ์ ์ ? ์์? ์ด๋ ํ ์ด๋ธ์ ๋ช ์ํด์ค์ผํ ๊น?
์ด๋ฅผ ์ ์ ๋ ์์ ํ ์ด๋ธ์ ๋ฃ๊ฒ ๋๋ฉด ๋๋ค ์ฌ์ฉ์, ์์ ๋ด์ฉ์ด ์ค๋ณต๋๋ ์ด์๊ฐ ๋ฐ์ํ๋ค.
์ด๋ ๊ฒ user_id ์ปฌ๋ผ์ 1๋ฒ 2๋ฒ ์ ์ ๊ฐ ์ฃผ๋ฌธํ๋ค. ๋ผ๋ ํํ ๋ฐฉ์๋ ์๋ ๊น?
์ผ๋จ RDBMS ์์์๋ ๋ถ๊ฐ๋ฅํ๋ค. ๋ผ๊ณ ์ดํดํ์.
- 2 row ๋ก ํํ์ด ๋๊ธด ํ๋ค! ๊ทธ๋ฌ๋ ์์์ ์ด๋ฆ์ด ๋ถํ์ํ๊ฒ ์ค๋ณต๋๋ค!
<ํด๊ฒฐ๋ฐฉ์>
์ฃผ๋ฌธ ์ ๋ณด๋ฅผ ๋ฃ์ ์ค๊ฐ ํ ์ด๋ธ์ ๋ฐ๋ก ๋ง๋ค์!
์ ๋ฆฌํด๋ณด๋ฉด ๊ณ ๊ฐ๋ ์์ ์ฌ๋ฌ๊ฐ๋ฅผ ์ฃผ๋ฌธํ ์ ์๊ณ ์์ ๋ํ ์ฌ๋ฌ ๊ณ ๊ฐ์๊ฒ ์ฃผ๋ฌธ๋ ์ ์๋ค. -> N:M ๊ด๊ณ!
N:M ๊ด๊ณ์ธ ํ ์ด๋ธ์ ์ฐ๊ด๊ด๊ณ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ค๊ฐํ ์ด๋ธ์ ์ฌ์ฉํ ์ ์๋ค.
<ํ ์ด๋ธ์ ๋ฐฉํฅ?>
- DB ํ ์ด๋ธ ๊ฐ ๋ฐฉํฅ์ด ์์๊น?
- ํ ์ด๋ธ์์๋ ์ํ๋ ์ ๋ณด๋ฅผ ๊ณ ๊ฐ, ์์ ์ด๋ ๊ธฐ์ค์ผ๋ก ํ๋ JOIN์ ์ฌ์ฉํด ์กฐํํ ์ ์์ผ๋ฉฐ
๋์ ๊ฒฐ๊ณผ๋ ์ค์ฐจ์์ด ๋๊ฐ๋ค. -> ๋ฐฉํฅ์ ๊ฐ๋ ์์
๊ทธ๋ ๋ค๋ฉด JPA Entity์์๋?
๊ฒฐ๋ก ์ ์ผ๋ก Entity์์๋ ๊ฐ๋ฅํ๋ค. ์ด๊ฒ์ด DB์ ์ ์ฉ๋๋ ๊ฒ์ ์๋์ง๋ง
๊ฐ์ฒด ํํ์์๋ ์ฐธ์กฐ๋ฅผ ๋จ๋ฐฉํฅ ์๋ฐฉํฅ ๋๊ฐ์ง ๋ชจ๋ ๋ค ๊ฐ๋ฅํ๋ค.
์ฐธ๊ณ ) ์ธ๋ ํค ์ฃผ์ธ๋ง์ด ์ธ๋ ํค๋ฅผ ๋ฑ๋ก, ์์ , ์ญ์ ํ ์ ์์ผ๋ฉฐ ์ฃผ์ธ์ด ์๋ ์ชฝ์ ์ค์ง ์ฝ๊ธฐ๋ง ๊ฐ๋ฅํ๋ค.
@JoinColumn ์ ๋ํ ์ด์ ์ผ๋ก ์ฃผ์ธ ์ง์
์์ ๋ฅผ ํตํด ํด๋น case๋ณ๋ก ํ์ธํด๋ณด์. (์ผ๊ด์ฑ์ ์ํด ์์ Entityd์๋ง ์ฃผ์ธ ๊ถํ์ ๋ถ์ฌํ๋ค.)
<1:1>
# 1:1 ๊ด๊ณ - ๋จ๋ฐฉํฅ
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@OneToOne
@JoinColumn(name = "user_id")
private User user;
}
- ๊ฐ์ฅ ๊ฐ๋จํ๋ค ์ฃผ์ธ์ธ ์ํฐํฐ์ 1:1 ๊ด๊ณ๋ฅผ ๋ํ๋ด๋ @OneToOne ์ ๋ํ ์ด์ ์์ฑ, ์ธ๋ํค์ ์ฃผ์ธ์์ ์๋ ค์ฃผ๋ @JoinColumn ์ ๋ํ ์ด์ ์์ฑํด์ฃผ๋ฉด ๋๋ค.
# 1:1 ๊ด๊ณ - ์๋ฐฉํฅ
-์ธ๋ํค์ ์ฃผ์ธ
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@OneToOne
@JoinColumn(name = "user_id")
private User user;
}
- ์ธ๋ํค ์ฃผ์ธ ์๋ ์ํฐํฐ
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne(mappedBy = "user")
private Food food;
}
- ์๋ฐฉํฅ ๊ด๊ณ์์๋ ์ฃผ์ธ์ด ์๋ ์ํฐํฐ์ ํ๋ ์ค์ ํ ๊ฒ์ด ์๋๋ฐ ๋ฐ๋ก mappedBy ์ต์ ์ด๋ค.
์ธ๋ํค์ ์ฃผ์ธ์ ์ง์ ํด์ค๋ ํด๋น ์ต์ ์ ์ฌ์ฉํ๋ฉฐ ์ง๊ธ ๋ณด์ด๋ "user"๋ผ๋ ์์ฑ๊ฐ์ User ํด๋์ค๋ฅผ ์๋ฏธํ๋ ๊ฒ์ด ์๋
์ธ๋ํค์ ์ฃผ์ธ์ธ Food ์ํฐํฐ์ ํ๋๋ช ์ ์๋ฏธํ๋ค. (ํท๊ฐ๋ฆฌ์ง ์๊ฒ ์ฃผ์)
- ๋ํดํธ ์ต์ ์ ์ฉ๋๊ธฐ ๋๋ฌธ์ ์๋ต์ด ๊ฐ๋ฅํ๊ธดํ๋ ๋ชจํธํ ๊ฒฝ์ฐ JPA์์ ์ค๊ฐํ ์ด๋ธ์ ์์ฑํ ์๋ ์๊ธฐ ๋๋ฌธ์ ๋ฐ๋์ ๋ช ์ํด์ฃผ๋ ๊ฒ์ด ์ข๋ค.
<N:1>
# N:1 ๊ด๊ณ - ๋จ๋ฐฉํฅ
- ์ด๋ 1:1 ๋จ๋ฐฉํฅ ๊ฒฝ์ฐ์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ฃผ์ธ ์ธ๋ํค ์ชฝ์ ์ ๋ํ ์ด์ ๋ง ์ ์์ฑํด์ฃผ๋ฉด ๋๋ค.
๋์ OneToOne ๋์ @ManyToOne ์ ๋ํ ์ด์ ์ ์ฌ์ฉํ๋ค.
# N:1 ๊ด๊ณ - ์๋ฐฉํฅ
- ์ด ๊ฒฝ์ฐ๋ 1:1 ์๋ฐฉํฅ ๊ฒฝ์ฐ์ ๋น์ทํ๋ค!
- ๋ค๋ง, ์ธ๋ํค์ ์ฃผ์ธ์ด ์๋ ํด๋์ค์ @OneToMany ๋ผ๋ ์ ๋ํ ์ด์ ์์ฑ ํ์.
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToOne //N:1 ๊ด๊ณ๋ฅผ ๋ํ๋ด๋ ์ ๋ํ
์ด์
@JoinColumn(name = "user_id") //์ธ๋ํค์ ์ฃผ์ธ์ ์ง์ ํ๋ ์ ๋ํ
์ด์
private User user;
}
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user") //์ธ๋ํค์ ์ฃผ์ธ์ ์๋ ค์ค.
//User ํด๋์ค ์๋๊ณ
//์ธ๋ํค์ ์ฃผ์ธ์ธ Food ํด๋์ค์ ํ๋์ธ user์!
private List<Food> foodList = new ArrayList<>();
}
- ํ๋ ์์ ๋ ๊ฒ์ ์๋ฐฉํฅ ์ฐธ์กฐ๋ฅผ ์ํด ๊ณ ๊ฐ ์ํฐํฐ์์ ์๋ฐ ์ปฌ๋ ์ ์ ์ฌ์ฉํ์ฌ ์์ ์ํฐํฐ๋ฅผ ์ฐธ์กฐํ๋ค! (์์์ ํ๋๋ง ์ฃผ๋ฌธํ ๊ฒ์ ์๋๊ธฐ์ ์ฌ๋ฌ๊ฐ๋ฅผ ๋ด์์ผํ๋ค.)
<1:N>
@OneToMany ์ ๋ํ ์ด์ ์ฌ์ฉ
์์์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ธ๋ํค ์ฃผ์ธ์ ์์์ผ๋ก ๋์.
๊ทธ๋ฐ๋ฐ 1:N ๊ด๊ณ์์ N์ ํ ์ด๋ธ์ด ์ธ๋ํค๋ฅผ ๊ฐ์ง ์ ์๊ธฐ ๋๋ฌธ์ ์ค์ ์ธ๋ํค๋ ๊ณ ๊ฐ์ ๋๋ค.
-๋จ๋ฐฉํฅ
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@OneToMany
@JoinColumn(name = "food_id") // users ํ
์ด๋ธ์ food_id ์ปฌ๋ผ
private List<User> userList = new ArrayList<>();
}
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
N ๊ด๊ณ์ธ User์ ์ ์ ์ธ๋ํค๋ฅผ ๋ณด๊ดํ๊ณ ์์์์ ๊ด๋ฆฌํ๋ค. ์ฐฝ๊ณ ๊ฐ์ ๋๋..
- ์๋ฐฉํฅ
ํด๋น ๊ด๊ณ์์๋ ์ผ๋ฐ์ ์ผ๋ก ์๋ฐฉํฅ ๊ด๊ณ๊ฐ ์กด์ฌํ์ง ์๋๋ค.
mappedBy ์์ฑ ๋ํ ์ ๊ณตํ์ง ์๋๋ค.
@JoinColumn์ insert/update์ false ๊ฐ์ ์ฃผ์ด ์๋ฐฉํฅ์ฒ๋ผ ์ค์ ํ ์๋ ์๋ค.
<N:M>
@ManyToMany ์ ๋ํ ์ด์ ์ฌ์ฉ
๊ธ ์๋จธ๋ฆฌ์์ ๋ดค๋ ๊ฒ์ฒ๋ผ ํด๋น ๊ด๊ณ์์๋ ์ค๊ฐํ ์ด๋ธ์ ๋ง๋ค์ด ์ฌ์ฉํ๋ค. (orders)
- ๋จ๋ฐฉํฅ
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToMany
@JoinTable(name = "orders")// ์ค๊ฐ ํ
์ด๋ธ ์์ฑ
joinColumns = @JoinColumn(name = "food_id"), // ํ์ฌ ์์น์ธ Food Entity ์์ ์ค๊ฐ ํ
์ด๋ธ๋ก ์กฐ์ธํ ์ปฌ๋ผ ์ค์
inverseJoinColumns = @JoinColumn(name = "user_id")) // ๋ฐ๋ ์์น์ธ User Entity ์์ ์ค๊ฐ ํ
์ด๋ธ๋ก ์กฐ์ธํ ์ปฌ๋ผ ์ค์
private List<User> userList = new ArrayList<>();
}
- ํด๋น orders ํ ์ด๋ธ์ JPA์ ์ํด ์๋์ผ๋ก ๋ง๋ค์ด์ง๋ค. PK ์กด์ฌํ์ง ์๋๋ค.
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
- ์๋ฐฉํฅ
- ์ธ๋ํค ์ฃผ์ธ์ด ์๋ ๊ณ ๊ฐ์ ์ฝ๋๋ง ๋ณ๊ฒฝ๋๋ค.
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany(mappedBy = "userList")
private List<Food> foodList = new ArrayList<>();
}
# N:M ์๋ฐฉํฅ ํ ์คํธ ์ฝ๋
@Test
@Rollback(value = false)
@DisplayName("N๋M ์๋ฐฉํฅ ํ
์คํธ : ๊ฐ์ฒด์ ์๋ฐฉํฅ์ ์ฅ์ ํ์ฉ")
void test5() {
User user = new User();
user.setName("Robbie");
User user2 = new User();
user2.setName("Robbert");
// addUserList() ๋ฉ์๋๋ฅผ ์์ฑํด user ์ ๋ณด๋ฅผ ์ถ๊ฐํ๊ณ
// ํด๋น ๋ฉ์๋์ ๊ฐ์ฒด ํ์ฉ์ ์ํด user ๊ฐ์ฒด์ food ์ ๋ณด๋ฅผ ์ถ๊ฐํ๋ ์ฝ๋๋ฅผ ์ถ๊ฐํฉ๋๋ค. user.getFoodList().add(this);
Food food = new Food();
food.setName("์๋ณด์นด๋ ํผ์");
food.setPrice(50000);
food.addUserList(user);
food.addUserList(user2);
Food food2 = new Food();
food2.setName("๊ณ ๊ตฌ๋ง ํผ์");
food2.setPrice(30000);
food2.addUserList(user);
userRepository.save(user);
userRepository.save(user2);
foodRepository.save(food);
foodRepository.save(food2);
// User ๋ฅผ ํตํด food ์ ์ ๋ณด ์กฐํ
System.out.println("user.getName() = " + user.getName());
List<Food> foodList = user.getFoodList();
for (Food f : foodList) {
System.out.println("f.getName() = " + f.getName());
System.out.println("f.getPrice() = " + f.getPrice());
}
}
- food.addUserList ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ๋ณด๋ค ๊ฐ์ฒด์งํฅ์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก ์ธ๋ํค๋ฅผ ์ค์ ํด์ค๋ค.
<์ค๊ฐํ ์ด๋ธ์ ์ง์ ์์ฑํ์ฌ ์์ฑํด๋ณด๊ธฐ>
- order ํ ์ด๋ธ์ ์ง์ ์์ฑํด์ ์ฌ์ฉํ๋ค. -> ๋ณ๊ฒฝ๋ฐ์์ ์ปจํธ๋กคํ๊ธฐ ์ฝ๊ธฐ ๋๋ฌธ์ ํ์ฅ์ฑ์ ์ฉ์ดํ๋ค.
@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "food_id")
private Food food;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
- ์ด์ ์ธ๋ํค์ ์ฃผ์ธ์ ์์, ๊ณ ๊ฐ์ด ์๋ ์ฃผ๋ฌธ์ด ๋๋ค.
'Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
TIL Spring #3-2 (0) | 2023.12.15 |
---|---|
TIL Spring #3-1 (0) | 2023.12.14 |
TIL Spring #2-5 (0) | 2023.12.13 |
TIL Spring #2-4 (0) | 2023.12.12 |
TIL Spring #2-3 (0) | 2023.12.12 |