1. DB table간의 연관 관계
1. DB 테이블의 관계 표현
- 우선적으로 아래 그림과 같이 음식과 고객 테이블이 있다고 가정해보자.


- 고객 테이블 기준 음식이 1: N인 경우
- 한 명이 여러 음식을 시킬 수 있다. 즉, 고객과 음식은 1 : N 관계라고 생각 해보면 우리는 아래의 그림과 같이 고객 테이블을 수정 할 수 있다.

- 하지만 이 테이블에는 불필요하게 고객의 이름이 중복되는 문제가 발생한다.
- 음식 테이블 기준 고객이 1: N인 경우
- 하나의 음식을 여러명이 시킬 수 있다. 즉, 음식과 고객은 1 : N 관계라고 생각 해보면, 아래의 그림과 같이 음식 테이블을 수정 할 수 있다.

- 후라이드 치킨을 여러 명이 시켰을 경우, 불필요하게 음식의 이름이 중복되는 문제가 발생한다.
- 해결 방법
- 위의 두 테이블의 문제점을 해결하기 위한 방법으로 우리는 아래의 그림과 같이 간단하게 배열을 생각 할 수 있다.

- 하지만 배열을 쓸 경우 user_id 값을 계속해서 추가할 때 뿐만 아니라 고객의 정보도 함께 조회가 필요할 때 많은 문제가 발생할 수 있기 때문에 현실적으로 불가능하다.
- 주문 테이블을 따로 만들 경우
- 위의 두 테이블만 비교했을 떄, 사실상 고객이랑 음식은 1 : N 관계인것이고, 옴식이랑 고객은 1 : N관계인 것을 알 수 있다.
즉, M :N 관계가 된다는 것을 알 수 있다.
- M : N 관계를 해결하기 위해서는 우린 새로운 주문 테이블을 만들 필요가 있다.

- 위의 그림과 같이 주문 테이블 따로 만들 경우,
- 서로의 1 : N 관계는 유지하면서 불필요한 중복 문제는 해결 할 수 있다.
2. DB 테이블의 방향성
- 방향성이란?
- 단반향일 경우는 유저 테이블에서만 음식 테이블을 참조 할 수 있어야하고, 음식 테이블에서만 유저 테이블을 참조 할 수 있어야한다.
- 양방향일 경우는 서로 참조가 가능 할 수 있어야한다.
- DB 테이블을 방향성이 존재 할까?
- 위의 테이블들을 이용해서 아래의 쿼리를 이용하면 , 우린 고객 'Robbie'가 주문한 음식 정보를 고객 테이블 기준으로 조회가 가능하다. 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;
- 그리고 아래의 쿼리를 이용하면, 음식 테이블 기준으로도 '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 테이블들 간에는 방향성이 존재하지 않는다.
2. Entity간의 연관 관계
1. JPA Entity 에서의 테이블간의 연관 관계 표현
- 음식 : 고객이 1 : N 관계일 경우, 즉 한명의 고객이 여러번 주문이 가능할 때, 아래의 코드와 같다.
@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;
@OneToMany(mappedBy = "user")
private List<Food> foodList = new ArrayList<>();
}
- 여기서 DB 테이블 간의 연관 관계의 차이점은 DB에서는 배열을 허락하지 않지만, entity에서는
List<Food> foodList = new ArrayList<>()
와 같이 배열을 허락하기 때문에 우린 주문 테이블 없이도 1 : N 관계를 문제 없이 표현 할 수 있다.
- DB 테이블에서는 join을 통해 고객 테이블 기준으로 음식 테이블을 조회가 가능하다. 하지만 entity같은 경우는 음식 필드값에 선언을 하지않으면 우린 고객 객체를 참조 할 수 없다. 즉, 선언을 함으로써 DB 테이블에 실제 컬럼으로 존재하지는 않지만 Entity 상태에서 다른 Entity를 참조할 수 있게 된다.
2. Entity의 방향성
- 양방향
- 위의 코드와 같이 서로의 entity에서 참조하고 있기 때문에 양방향이라고 할 수 있다.
- 단방향
- 아래의 코드와 같이 한 쪽의 entity에만 참조하고 있기 때문에 단방향이라고 할 수 있다.
@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에서는 DB 테이블에는 없는 방향의 개념이 존재한다.