프로젝트 기본 틀을 잡았으니 엔티티부터 설계해보도록 하겠다☺️
일단 기본적으로 연관관계 매핑까지만 고려했음
즐거운 마음으로 시~작 ^_^
Member
- 회원 엔티티package sorzzzzy.dearmydog.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter @Setter
public class Member {
@Id @GeneratedValue
@Column(name = "member_id")
private Long id;
private String name;
@Embedded
@Enumerated(EnumType.STRING) // 임베디드 타입은 '@Enumerated' 이 꼭 필요함
private Address address;
// 연관관계의 주인이 아닌 쪽에는 'mappedBy' 사용
// 여기서 member는 'Order 테이블에 있는 member 필드에 의해 mapped 됐다' 는 의미
@OneToMany(mappedBy = "member")
private List<Order> orders = new ArrayList<>();
}
@Enumerated
을 꼭 사용하기Order
- 주문 엔티티package sorzzzzy.dearmydog.domain;
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")
@Getter @Setter
public class Order {
@Id @GeneratedValue
@Column(name = "order_id")
private Long id;
@ManyToOne
@JoinColumn(name = "member_id") // foreign key 는 '다'인 order 가 가짐
private Member member;
@OneToMany(mappedBy = "order")
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne
@JoinColumn(name = "delivery_id") // 일대일인 경우, FK는 아무곳에나 있어도 되는데 여기서는 접근을 더 많이 하는 order 에 둠
private Delivery delivery;
private LocalDateTime orderDate;
private OrderStatus status;
}
foriegn key
를 가지는 엔티티가 어떤 엔티티인지 잘 고려해보자!
Order
에 맞춤OrderItem
- 주문상품 엔티티package sorzzzzy.dearmydog.domain;
import lombok.Getter;
import lombok.Setter;
import sorzzzzy.dearmydog.domain.Item.Item;
import javax.persistence.*;
@Entity
@Getter @Setter
public class OrderItem {
@Id @GeneratedValue
@Column(name = "order_item_id")
private Long id;
@ManyToOne
@JoinColumn(name = "item_id")
private Item item;
@ManyToOne
@JoinColumn(name = "order_id")
private Order order;
private int orderPrice;
private int count;
}
Delivery
- 배송 엔티티package sorzzzzy.dearmydog.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Getter @Setter
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;
}
@Embedded
필요Enum
타입을 가지는 DeliveryStatus
는 @Enumerated(EnumType.STRING)
필요Address
- 주소(값타입)package sorzzzzy.dearmydog.domain;
import lombok.Getter;
import javax.persistence.Embeddable;
@Embeddable
@Getter
public class Address {
private String city;
private String street;
private String zipcode;
// JPA 스펙 상 엔티티나 임베디드 타입은 기본 생성자를 protected 또는 public 으로 설정해야 함
protected Address() {
}
// 값 타입은 변경 불가능하게 설계해야 함
// setter를 제거하고 생성자에서 값을 모두 초기화해 변경 불가능한 클래스를 만듦
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
}
protected
또는 public
으로 설정해야 함setter
를 제거하고 생성자에서 값을 모두 초기화해 변경 불가능한 클래스를 만듦Item
- 상품 엔티티package sorzzzzy.dearmydog.domain.Item;
import lombok.Getter;
import lombok.Setter;
import sorzzzzy.dearmydog.domain.Category;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
// 상속관계 지정 - 싱글테이블 전략
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
// dtype 으로 분류
@DiscriminatorColumn(name = "dtype")
@Getter @Setter
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<>();
}
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
로 상속관계 지정Toy
package sorzzzzy.dearmydog.domain.Item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@Getter
@Setter
@DiscriminatorValue("T")
public class Toy extends Item{
private String component;
private String size;
}
Food
package sorzzzzy.dearmydog.domain.Item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@Getter
@Setter
@DiscriminatorValue("F")
public class Food extends Item {
private String allowance;
private String ingredient;
}
Clothes
package sorzzzzy.dearmydog.domain.Item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@Getter
@Setter
@DiscriminatorValue("C")
public class Clothes extends Item {
private String season;
private String color;
}
Category
- 카테고리 엔티티package sorzzzzy.dearmydog.domain;
import lombok.Getter;
import lombok.Setter;
import sorzzzzy.dearmydog.domain.Item.Item;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter @Setter
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<>();
@ManyToOne
@JoinColumn(name = "parent_id")
private Category parent;
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();
}
카테고리 엔티티는 상품과 다대다 관계인데 이것을 일대다, 다대일로 풀어내기 위해서는 중간테이블이 필요하다!
@JoinTable
로 각각을 중간테이블에 매핑함 @ManyToOne
@JoinColumn(name = "parent_id")
private Category parent;
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();
이처럼 한 엔티티 안에서 간편하게 상속관계를 지정할 수 있다.
➡️쿼리가 아주 깔끔하죠? 굳^^➡️ h2 데이터베이스에도 잘 반영된 것을 확인
다음 시간부터는 이제 연관관계를 지연로딩으로 바꾸고 도메인을 차례로 개발해보겠다!