스프링 Entity 연관 관계

심규원·2024년 8월 20일


이러한 테이블을 만든다고 치면 관계는 어떻게 되는가.

  1. 고객 테이블
    • 한명의 고객은 음식을 여러개를 주문할 수 있습니다.
      • 고객과 음식은 1 대 N 관계입니다.
  2. 음식 테이블
    • 하나의 음식은 여러명의 고객에게 주문될 수 있습니다.
      • 음식과 고객은 1 대 N 관계입니다.

후라이트 치킨을 여러사람이 주문하게 되었을 떄 불필요하게 음식의 이름이 중복되는 문제가 발생.

그래서 이러한 관계를 풀어주기 위해 주문(Order) 라는 테이블을 하나더 추가해주는 방식.

  • 고객 1명은 음식 N개를 주문할 수 있다.
    • 고객 : 음식 = 1 : N 관계
  • 음식 1개는 고객 N명에게 주문될 수 있다.
    • 음식 : 고객 = 1 : N 관계
  • 결론적으로 고객과 음식은 N : M 관계.
    • 고객 : 음식 = N : M 관계



  • 이렇듯 N : M 관계인 테이블들의 연관 관계를 해결하기 위해 orders 테이블처럼 중간 테이블을 사용할 수 있다.
    • 고객 1명은 주문을 여러번 할 수 있다.
      • 고객 : 주문 = 1 : N
    • 음식 1개는 주문이 여러번 될 수 있다.
      • 음식 : 주문 = 1 : N

DB 테이블들간의 관계에서 방향의 개념은 존재 하지 않는다.

방향에는 크게 단방향과 양방향을 생각해 볼 수 있다.

예를 들어 단방향은 users 테이블에서만 food 테이블을 참조할 수 있을 때를 의미 한다.
양방향은 users 테이블과 food 테이블이 서로를 참조할 수 있을 때를 의미 한다.

이렇지만 어떤 테이블을 기준으로 하든 원하는 정보를 Join 을 통해 조회할 수 있다.

그렇다면 JPA 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에서 여러번 가능함을 표현하기 위해 Java 컬렉션을 사용하여 List<Food> foodList = new ArrayList<>() 이처럼 표현할 수 있다.
  • 그렇다면 Entity에서 이렇게까지 해서 표현을 하는 이유가 무엇일까?
    • DB 테이블에서는 고객 테이블 기준으로 음식의 정보를 조회하려고 할 때 JOIN을 사용하여 바로 조회가 가능하지만 고객 Entity 입장에서는 음식 Entity의 정보를 가지고 있지 않으면 음식의 정보를 조회할 방법이 없다.
    • 따라서 DB 테이블에 실제 컬럼으로 존재하지는 않지만 Entity 상태에서 다른 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에는 음식 Entity의 정보가 없기 때문에 음식 정보를 조회할 수 없다.
  • DB 테이블에서는 테이블 사이의 연관관계를 FK(외래 키)로 맺을 수 있고 방향 상관없이 조회가 가능.
  • Entity에서는 상대 Entity를 참조하여 Entity 사이의 연관관계를 맺을 수 있다.
  • 하지만 상대 Entity를 참조하지 않고 있다면 상대 Entity를 조회할 수 있는 방법이 없다.
  • 따라서 Entity에서는 DB 테이블에는 없는 방향의 개념이 존재한다.

0개의 댓글