도메인 모델과 테이블 설계

엔티티 분석

테이블 분석

회원 엔티티
@Entity
@Getter @Setter
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<>();
}
주문 엔티티
@Entity
@Table(name = "orders")
@Getter@Setter
public class Order{
@Id@GeneratedValue
@Colunm(name = "Order_id")
private Long id;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "delivery_id")
private Delivery delivery;
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
pirvate OrderStatus stauts;
//연관관계 편의 메서드
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 = this
delivery.setOrder(this);
}
주문상태
public void enum OrderStatus{
ORDER,CANCEL
}
주문상품 엔티티
@Entity
@Getter@Setter
public class OrderItem{
@Id@GeneratedValue
@Table(name = "order_item")
@Column(name="order_item_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="order_id")
private Order order;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="item_id")
private Item item;
private int orderPrice;
private int count;
}
상품 엔티티
@Entity
@Getter
@Setter
@Inheritance = (strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dypte")
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>();
}
상품 - 도서 엔티티
@Entity
@Getter@Setter
@DiscriminatorValue("B")
public class Book extends Item{
private String author;
private String isbn;
}
상품 - 음반 엔티티
@Entity
@Getter@Setter
@DiscriminatorValue("A")
public class Album extens Item{
private String artist;
private String etc;
}
상품 - 영화 엔티티
@Entity
@Getter@Setter
@DiscriminatorValue("M")
public class Movie extens Item{
private String director;
private String actor;
}
배송 엔티티
@Entity
@Getter@Setter
public class Delivery{
@Id@GeneratedValue
@Column(name ="delivery_id")
private Long id;
@OneToOne(mappedBy="delivery",fetch = FetchType.LAZY)
private Ordre order;
@Embedded
private Address address;
@Enumerated
private DeliveryStatus deliverystatus;
}
배송상태
public enum DeliveryStatus{
READY,COMP
}
카테고리 엔티티
@Entity
@Getter@Setter
public class Category{
@Id@GeneratedValue
@Column(name = "category_id")
private Long id;
private String name;
@ManyToMany
@JoinTable(name = "category_itme", joinColumns = @joinColumn(name = "category_id), inverseJoinColumns = @JoinColumn(name = "item_id))
private List<Item> items = new arrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name ="parent_id")
private Category parent;
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();
//연관관계 편의 메서드
public void addChildCategory(Category child){
this.child.add(child);
child.setParent(this);
}
}
주소 값 타입
@Embeddable
@Getter
public class Address{
private Stirng city;
private String street;
private STring zipcode;
protect Address(){
}
public Address(String city, STring street, String zipcode){
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
}
엔티티 설계시 주의점
- 엔티티에는 가급적 Setter를 사용하지 말자
- 변경포인트가 너무 많아 유지보수가 어려워 진다.
- 모든 연관관계는 지연로딩으로 설정!
- 즉시로딩은 예측이 어렵고 추적하기 어려우며, JPQL사용시 N+1 문제가 자주 발생한다.
- @XToOne 관계는 직접 지연로딩으로 설정해야 한다
- 컬렉션은 필드에서 초기화 하자
댓글남기기