연관 관계 매핑

jihan kong·2023년 2월 15일
0
post-thumbnail

Entity 들 간의 연관 관계를 매핑

1. 연관 관계 매핑의 종류

프로젝트를 위해 공부를 하면서 연관 관계 매핑에는 총 4가지의 매핑 관계가 있다는 것을 알게 되었다.

  • 일대일 (1:1) : @OneToOne
  • 일대다 (1:N) : @OneToMany
  • 다대일 (N:1) : @ManyToOne
  • 다대다 (N:M) : @ManyToMany

또한, 방향성도 존재하는데 단방향 (한쪽에서 다른 한쪽) 과 양방향 이 있다.

장바구니 기능을 추가하면서 장바구니는 회원과 일대일 단방향 관계임을 알게 되었다. 이러한 연관관계를 토대로 Entity를 설계하였다.

2. 장바구니 (Cart) Entity 설계 (일대일 단방향)

Cart.java

package com.shop.entity;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.persistence.*;

@Entity
@Table(name = "cart")
@Getter @Setter
@ToString
public class Cart {

    @Id
    @Column(name = "cart_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToOne
    @JoinColumn(name="member_id")              
    private Member member;
}
  • @OneToOne 을 이용. 회원 엔티티와 일대일 매핑
  • @JoinColumn 어노테이션을 통해 매핑할 외래키 지정

Cart Entity ➡️ Member Entity
장바구니 엔티티가 회원 엔티티를 참조하는 일대일 단방향 매핑


3. 장바구니 아이템 (CartItem) Entity 설계 (다대일 단방향)

  • 하나의 장바구니에는 여러 개의 장바구니 아이템(Cart_item)이 존재하고, 장바구니 아이템은 실제 상품(item)과 일대일로 매칭된다.

CartItem.java

package com.shop.entity;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;

@Entity
@Getter
@Setter
@Table(name="cart_item")
public class CartItem {

    @Id
    @GeneratedValue
    @Column(name = "cart_item_id")
    private Long id;

    @ManyToOne				// 1.
    @JoinColumn(name = "cart_id")
    private Cart cart;

    @ManyToOne        		// 2.
    @JoinColumn(name = "item_id")
    private Item item;
    
    private int count;
}
  1. 하나의 장바구니에는 여러 개의 상품을 담을 수 있으므로 @ManyToOne 다대일 매핑
  2. 상품 엔티티 또한, 하나의 상품이 여러 장바구니 상품으로 담길 수 있으므로 @ManyToOne 다대일 매핑

4. 주문과 주문 상품 Entity 설계 (다대일/일대다 양방향)

  • 한 명의 회원은 여러 개의 주문을 넣을 수 있다. 또한, 여러 개의 주문은 여러 명의 회원을 가질 수 있다. 단방향 매핑이 2개라고 생각하면 양방향 매핑이 쉽다.

먼저, 주문 상태를 나타내는 OrderStatus enum class를 만들었다. 주문을 한 상태는 Order, 취소상태는 Cancel 2가지로 나타내었다.

OrderStatus.java

package com.shop.constant;

public enum OrderStatus {
    ORDER, CANCEL
}

4-1. 주문 Entity 설계

Order.java

package com.shop.entity;

import com.shop.constant.OrderStatus;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "orders")						// 1.
@Getter
@Setter
public class Order {

    @Id
    @GeneratedValue
    @Column(name = "order_id")
    private Long id;

    @ManyToOne								// 2.
    @JoinColumn(name = "member_id")
    private Member member;                 

    private LocalDateTime orderDate;        // 주문일

    @Enumerated(EnumType.STRING)
    private OrderStatus orderStatus;        // 주문 상태

    @OneToMany(mappedBy = "order")			// 3.
    private List<OrderItem> orderItems = new ArrayList<>() 
    									    // 4.
    
   	private LocalDateTime regTime;
   
   	private LocalDateTime updateTime;
  1. Order Entity에 매핑되는 테이블로 "Orders" 를 지정 (정렬할 때 사용하는 "order" 키워드가 이미 있기 때문
  2. 한 명의 회원은 여러 번 주문을 할 수 있기 때문에 주문 엔티티 기준에서 다대일 단방향 매핑
  3. 주문 상품 Entity와 일대다 매핑
    -> Order Entity 가 주인이 아니기 때문에 "mappedBy" 속성으로 연관 관계의 주인을 설정
  4. 하나의 주문이 여러 개의 주문 상품을 가지므로 List 자료형을 사용해서 매핑

4-2. 주문상품(OrderItem) Entity 설계

OrderItem.java

package com.shop.entity;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Getter
@Setter
public class OrderItem {

    @Id
    @GeneratedValue
    @Column(name = "order_item_id")
    private Long id;

    @ManyToOne
    @JoinColumn(name = "item_id")
    private Item item;     // 1.            

	@ManyToOne
	@JoinColumn(name = "order_id")
    private Order order;   // 2.     
    
    private int orderPrice;	// 주문 가격

    private int count;
    
    private LocalDateTime regTime;
    
    private LocalDateTime updateTime;
   
  1. 하나의 상품은 여러 주문 상품으로 들어갈 수 있기 때문에 주문 상품 기준 다대일 단방향 매핑
  2. 한 번의 주문에 여러 개의 상품을 주문할 수 있으므로 주문 상품 엔티티와 다대일 단방향 매핑

배운 것

  • 두 엔티티를 양방향 연관 관계로 설정하면 둘 중 누가 외래키를 관리할지를 정해야한다.
    • 연관 관계의 주인은 외래키가 있는 곳으로 설정하자.
    • 주인이 외래키를 관리한다(등록, 수정, 삭제)
    • 주인이 아닌 쪽은 연관 관계 매핑 시 mappedBy 속성의 값으로 연관 관계의 주인을 설정한다.
profile
학습하며 도전하는 것을 즐기는 개발자

0개의 댓글