2 minute read

도메인 모델과 테이블 설계

17


엔티티 분석

18


테이블 분석

19


회원 엔티티

@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;
    }
}


엔티티 설계시 주의점

  1. 엔티티에는 가급적 Setter를 사용하지 말자
    • 변경포인트가 너무 많아 유지보수가 어려워 진다.
  2. 모든 연관관계는 지연로딩으로 설정!
    • 즉시로딩은 예측이 어렵고 추적하기 어려우며, JPQL사용시 N+1 문제가 자주 발생한다.
    • @XToOne 관계는 직접 지연로딩으로 설정해야 한다
  3. 컬렉션은 필드에서 초기화 하자

댓글남기기