Spring 28. N:M

김창민·2024년 8월 20일

BE

목록 보기
49/50

@ManyToMany 어노테이션은 N 대 M 관계를 맺어준다.

단방향

N:M 관계에서는 중간 테이블이 필요하다.
중간 테이블의 이름을 orders, 조인할 컬럼을 food_id, user_id로 설정하면 다음과 같다

@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", // create orders table
    joinColumns = @JoinColumn(name = "food_id"), // Food Entity's join column
    inverseJoinColumns = @JoinColumn(name = "user_id")) // User Entity's join column
    private List<User> userList = new ArrayList<>();
}

다만, 생성되는 중간 테이블을 컨트롤하기 어렵기 때문에 중간 테이블 변경시 문제 발생의 위험이 있다.


양방향

@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", // create orders table
    joinColumns = @JoinColumn(name = "food_id"), // Food Entity's join column
    inverseJoinColumns = @JoinColumn(name = "user_id")) // User Entity's join column
    private List<User> userList = new ArrayList<>();
}
@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<>();
}

고객 Entity에 @ManyToMany로 연결하고, mappedBy 옵션으로 외래 키의 주인을 설정하면 양방향 관계가 가능하다.


중간 테이블

위의 경우 중간테이블을 간접적으로 생성했지만, 직접 생성하면 변경 발생시 컨트롤이 쉬워 확장성에 좋다.

@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    @OneToMany(mappedBy = "food")
    private List<Order> orderList = new ArrayList<>();
}
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany(mappedBy = "user")
    private List<Order> orderList = new ArrayList<>();
}
@Entity
@Table(name = "orders")
@EntityListeners(AuditingEntityListener.class) //main에 EnableJpaAuditing
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;

    @CreatedDate
    @Temporal(TemporalType.TIMESTAMP)
    private LocalDateTime orderDate;
}

이 경우 중간 테이블이 오래키를 모두 소지하고, 음식, 고객이 접근하는 형식으로 바뀐다.

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

0개의 댓글