Spring 24. Entity

김창민·2024년 8월 20일

BE

목록 보기
45/50

DB table

테이블간 연관 관계
고객 테이블과 음식 테이블이 있을때,
고객이 음식을 주문하면, 주문 정보는 어느 테이블에 들어가는가?
정답은 "중간 테이블이 필요하다" 이다.

  • 고객 테이블의 경우

한명의 고객이 여러 음식을 주문할 수 있다. -> 고객:음식=1:N
Kim이 불고기 피자(1), 포테이토 피자(2)를 주문하면 고객 테이블에 다음과 같이 저장된다.

INSERT INTO users (name, food_id) VALUES ('Kim', 1);
INSERT INTO users (name, food_id) VALUES ('Kim', 2);

이 경우 Kim이라는 고객이 중복 생성되어 id를 1,2를 할당받는 문제가 생긴다.

  • 음식 테이블의 경우
    하나의 음식은 여러 고객에게 주문될 수 있다. 음식:고객=1:N
    후라이트 치킨이 1,2번 고객에게 주문되면 음식 테이블에 다음과 같이 저장된다.
INSERT INTO food (name, price, user_id) VALUES ('후라이드 치킨', 15000, 1);
INSERT INTO food (name, price, user_id) VALUES ('후라이드 치킨', 15000, 2);

이 경우도 불필요하게 음식의 이름이 중복 생성되는 문제가 발생한다.

위 두 경우를 종합하면 고객:음식=1:N, 음식:고객=1:N 즉 고객:음식=N:M 이라고 볼 수 있다.
N:M 연관 관계의 테이블은 중간 테이블을 생성해서 연관 관계를 해결 할 수 있게 된다.

  • 중간 테이블의 경우
  INSERT INTO orders (user_id, food_id, order_date) VALUES (1, 1, SYSDATE());
  INSERT INTO orders (user_id, food_id, order_date) VALUES (2, 1, SYSDATE());
  INSERT INTO orders (user_id, food_id, order_date) VALUES (2, 2, SYSDATE());
  INSERT INTO orders (user_id, food_id, order_date) VALUES (1, 4, SYSDATE());
  INSERT INTO orders (user_id, food_id, order_date) VALUES (2, 3, SYSDATE());

처럼 유저, 음식, 날짜를 이용해서 중복없이 처리할 수 있다.

이렇게 3개의 테이블을 sql로 조회하기 위해선 join문을 사용할 수 있는데,
join문은 동일한 column이 있으면 가능하기 때문에 방향이라는 개념은 존재하지 않는다.


Entity간 연간 관계

한명의 고객이 여러 음식을 주문할 수 있는 음식:고객=N:1 관계인 경우
고객 Entity에서 List<Food> foodList = new ArrayList<>()를 통해 여러번 접근이 가능함을 표현할 수 있다.
DB 테이블은 join을 통해서 바로바로 접근이 가능하지만, Entity는 필드에 해당 정보가 없으면 조회가 불가능하기 때문이다.
따라서 테이블에 실제 column으론 존재하지 않지만 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: @ManyToOne라는 관계 어노테이션과 @JoinColumn라는 외래 키 column 지정 어노테이션을 사용
고객 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;

  @OneToMany(mappedBy = "user")
  private List<Food> foodList = new ArrayList<>();
}

음식 Entity: 단방향의 상태와 동일
고객 Entity: @OneToMany라는 관계 어노테이션이 생겼고, mappedBy = "user" 옵션을 통해 Food 엔터티의 user 필드에 의해 매핑됨을 알린다.
물론 Food Entity는 아래 List를 통해 알게되는 것이고, user는 Food의 private User user;를 말하는 것이다.


profile
일일 회고 : https://rlackdals981010.github.io/

0개의 댓글