테이블 간 관계
고객 정보를 가진 users 테이블
create table users
(
id bigint not null auto_increment,
name varchar(255),
primary key (id)
);
음식 정보를 가진 food 테이블
create table food
(
id bigint not null auto_increment,
name varchar(255),
price float(53) not null,
primary key (id)
);
둘을 이어주는 주문 정보를 가진 orders 테이블
create table orders
(
id bigint not null auto_increment,
user_id bigint,
food_id bigint,
order_date date,
primary key (id)
);
alter table orders
add constraint orders_user_fk
foreign key (user_id)
references users (id);
alter table orders
add constraint orders_food_fk
foreign key (food_id)
references food (id);
DB table간의 방향
- 방향에는 크게 단방향과 양방향을 생각해 볼 수 있습니다.
- 예를 들어 단방향은 users 테이블에서만 food 테이블을 참조할 수 있을 때를 의미합니다.
- 양방향은 users 테이블과 food 테이블이 서로를 참조할 수 있을 때를 의미합니다.
- 그렇다면 DB 테이블간의 방향이 있는 게 맞을까요?
- 고객 ‘Robbie’가 주문한 음식 정보를 users 테이블 기준으로 조회
SELECT u.name as username, f.name as foodname, o.order_date as orderdate
FROM users u
INNER JOIN orders o on u.id = o.user_id
INNER JOIN food f on o.food_id = f.id
WHERE o.user_id = 1;
- food 테이블 기준으로는 ‘Robbie’가 주문한 음식 정보를 조회
SELECT u.name as username, f.name as foodname, o.order_date as orderdate
FROM food f
INNER JOIN orders o on f.id = o.food_id
INNER JOIN users u on o.user_id = u.id
WHERE o.user_id = 1;
- DB에서는 어떤 테이블을 기준으로 하든 원하는 정보를 JOIN을 사용하여 조회할 수 있습니다.
- 이처럼 DB 테이블간의 관계에서는 방향의 개념이 없습니다.
- 이렇듯 N : M 관계인 테이블들의 연관 관계를 해결하기 위해 orders 테이블처럼 중간 테이블을 사용할 수 있습니다.
- 고객 1명은 주문을 여러번 할 수 있습니다.
- 고객 : 주문 = 1 : N
- 음식 1개는 주문이 여러번 될 수 있습니다.
- 음식 : 주문 = 1 : N
- 고객 1명은 주문을 여러번 할 수 있습니다.
Entity간의 연관 관계
그렇다면 JPA Entity에서는 이러한 테이블간의 연관 관계를 어떻게 표현하고 있을까요?
음식 : 고객 = N : 1 관계를 표현
1. 양방향
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
import java.util.ArrayList;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user")
private List<Food> foodList = new ArrayList<>();
}
- 현재 음식 Entity와 고객 Entity는 서로를 참조하고 있습니다(양방향).
한명의 고객은 여러번 주문이 가능한 상황입니다.
- 이를 Entity에서 여러번 가능함을 표현하기 위해 Java 컬렉션을 사용하여 List<Food> foodList = new ArrayList<>() 이처럼 표현할 수 있습니다.
그렇다면 Entity에서 이렇게까지 해서 표현을 하는 이유가 무엇일까요?
- DB 테이블에서는 고객 테이블 기준으로 음식의 정보를 조회하려고 할 때 JOIN을 사용하여 바로 조회가 가능하지만 고객 Entity 입장에서는 음식 Entity의 정보를 가지고 있지 않으면 음식의 정보를 조회할 방법이 없습니다.
- 따라서 DB 테이블에 실제 컬럼으로 존재하지는 않지만 Entity 상태에서 다른 Entity를 참조하기 위해 이러한 방법을 사용합니다.
2. 단반향
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToOne
@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;
}
- 음식 Entity에서만 고객 Entity를 참조할 수 있습니다(단방향).
- 고객 Entity에는 음식 Entity의 정보가 없기 때문에 음식 정보를 조회할 수 없습니다.
<정리>
- DB 테이블에서는 테이블 사이의 연관관계를 FK(외래 키)로 맺을 수 있고 방향 상관없이 조회가 가능합니다.
- Entity에서는 상대 Entity를 참조하여 Entity 사이의 연관관계를 맺을 수 있습니다.
- 하지만 상대 Entity를 참조하지 않고 있다면 상대 Entity를 조회할 수 있는 방법이 없습니다.
- 따라서 Entity에서는 DB 테이블에는 없는 방향의 개념이 존재합니다.
'Spring > 팀스파르타' 카테고리의 다른 글
37. Entity 연관관계 - N 대 1 (0) | 2024.12.06 |
---|---|
36. Entity 연관 관계 - 1 대 1 (0) | 2024.12.06 |
34. RestTemplate의 Post 요청, exchange (0) | 2024.11.27 |
33. RestTemplate이란 무엇일까? (0) | 2024.11.25 |
31. Spring Security: JWT 로그인 (0) | 2024.11.21 |