작은 쇼핑몰을 설계하고 만들어보자 !
(1) 회원 기능
(2) 상품 기능
(3) 주문 기능
(4) 기타 요구사항
🔻 회원, 주문, 상품의 관계
🔻 상품 분류
🔻 객체 도메인 모델을 매핑하기 위해 설계한 테이블
MEMBER
ITEM
🔽 회원과 주문
🔽 주문상품과 주문
🔽 주문상품과 상품
🔽 주문과 배송
🔽 카테고리와 상품
단, 실무에서는 복잡성과 관리 어려움의 이유 등으로 @ManyToMany를 잘 사용하지 않지만 다양한 매핑 방법 실습을 위해 추가됨!
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String name;
@Embedded
private Address address;
@OneToMany(mappedBy = "member")
private List<Order> orders = new ArrayList<Order>();
// Getter, Setter
...
}
@Entity
@Table(name = "ORDERS")
public class Order {
@Id @GeneratedValue
@Column(name = "ORDER_ID")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "MEMBER_ID")
private Member member; // 주문 회원
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<OrderItem>();
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "DELIVERY_ID")
private Delivery delivery; // 배송정보
private Date orderDate; // 주문시간
@Enumerated(EnumType.STRING)
private OrderStatus status; // 주문상태
//==연관관계 메소드==//
public void setMember(Member member) {
this.member = member;
member.getOrders().add(this);
}
public void addOrderItem(OrderItem orderItem) {
orderItems.add(orderItem);
orderItem.setOrder(this);
}
public void setDelivery(Delivery delivery) {
this.delivery = delivery;
delivery.setOrder(this);
}
// Getter, Setter
...
}
@Entity
@Table(name = "ORDER_ITEM")
public class OrderItem {
@Id @GeneratedValue
@Column(name = "ORDER_ITEM_ID")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ITEM_ID")
private Item item; // 주문 상품
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ORDER_ID")
private Order order; // 주문
private int orderPrice; // 주문 가격
private int count; // 주문 수량
// Getter, Setter
...
}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item {
@Id @GeneratedValue
@Column(name = "ITEM_ID")
private Long id;
private String name; // 이름
private int price; // 가격
private int stockQuantity; // 재고수량
@ManyToMany(mappedBy = "items")
private List<Category> categories = new ArrayList<Category>();
// Getter, Setter
...
}
@Entity
@DiscriminatorValue("B")
public class Book extends Item {
private String author;
private String isbn;
// Getter, Setter
...
}
@Entity
@DiscriminatorValue("A")
public class Album extends Item {
private String artist;
private String etc;
// Getter, Setter
...
}
@Entity
@DiscriminatorValue("M")
public class Movie extends Item {
private String director;
private String actor;
// Getter, Setter
...
}
@Entity
public class Delivery {
@Id @GeneratedValue
@Column(name = "DELIVERY_ID")
private Long id;
@OneToOne(mappedBy = "delivery")
private Order order;
@Embedded
private Address address;
@Enumerated(EnumType.STRING)
private DeliveryStatus status; // ENUM [READY(준비), COMP(배송)]
// Getter, Setter
...
}
@Entity
public class Category {
@Id @GeneratedValue
@Column(name = "CATEGORY_ID")
private Long id;
private String name;
@ManyToMany
@JoinTable(name = "CATEGORY_ITEM",
joinColumns = @JoinColumn(name = "CATEGORY_ID"),
inverseJoinColumns = @JoinColumn(name = "ITEM_ID"))
private List<Item> items = new ArrayList<Item>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PARENT_ID")
private Category parent;
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<Category>();
//==연관관계 메서드==//
public void addChildCategory(Category child) {
this.child.add(child);
child.setParent(this);
}
// Getter, Setter
...
}
@Embeddable
public class Address {
private String city;
private String street;
private String zipcode;
// Getter, Setter
...
}
위와 같은 코드로 엔티티와 테이블 설계를 완성하였다. 이 엔티티를 기반으로 다음 포스팅에서는 실제 애플리케이션을 개발해보자!
➕ 참고 : 기본 키 이름과 엔티티 식별자 이름
테이블의 기본 키 컬럼 이름은 해당 테이블 이름을 포함하도록 함. 엔티티는 연관된 엔티티를 참조할 때 타입이 있으므로 엔티티의 식별자를 단순히 id로 지어도 어떤 엔티티를 참조하는지 쉽게 알 수 있지만, 테이블의 기본 키나 외래 키는 단순히 값만 저장하지 어떤 테이블과 관계가 있는지 외래 키 제약조건을 참고하지 않으면 알 수 없다!