1. 엔티티 클래스 개발
🚨 @Setter 사용을 지양해야 하는 이유
- 이론적으로
Getter
, Setter
를 모두 제공하지 않고 꼭 필요한 별도의 메서드를 제공하는 것이 가장 이상적이지만, 실무에서는 엔티티의 데이터는 조회할 일이 많기 때문에 Getter
의 경우 모두 열어두는 것이 편리함
Getter
는 애초에 조회만 수행하는 것이 때문에 사용한다고 해서 큰 문제가 발생하지는 않음
- 하지만,
Setter
의 경우 호출하면 데이터가 변하기 때문에, Setter
를 열어두면 가까운 미래에 엔티티가 어떻게 변경될 것인지 추적하기가 힘들어짐
- 따라서 엔티티를 변경할 때는 변경 지점이 명확하도록 비즈니스 메서드를 별도로 제공해야 함
Member Entity
@Entity
@Getter
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
@Entity
@Table(name = "orders")
@Getter @Setter
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<>();
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "delivery_id")
private Delivery delivery;
private LocalDateTime 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);
}
}
OrderStatus Enum
public enum OrderStatus {
ORDER, CANCEL
}
OrderItem Entity
@Entity
@Table(name = "order_item")
@Getter @Setter
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;
}
Item Entity
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dtype")
@Getter
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>();
}
Item - Book Entity
@Entity
@DiscriminatorValue("B")
@Getter
public class Book extends Item {
private String author;
private String isbn;
}
Item - Album Entity
@Entity
@DiscriminatorValue("A")
@Getter
public class Album extends Item {
private String artist;
private String etc;
}
Item - Movie Entity
@Entity
@DiscriminatorValue("M")
@Getter
public class Movie extends Item {
private String director;
private String actor;
}
Delivery Entity
@Entity
@Getter @Setter
public class Delivery {
@Id @GeneratedValue
@Column(name = "delivery_id")
private Long id;
@OneToOne(mappedBy = "delivery", fetch = FetchType.LAZY)
private Order order;
@Embedded
private Address address;
@Enumerated(EnumType.STRING)
private DeliveryStatus status;
}
DeliveryStatus Enum
public enum DeliveryStatus {
READY, COMP
}
Category Entity
@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(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);
}
}
Address Entity
@Embeddable
@Getter
public class Address {
private String city;
private String street;
private String zipcode;
protected Address() {
}
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
}
- 값 타입은 변경 불가능하게 설계해야 함
@Setter
를 제거하고 생성자에서 값을 모두 초기화해서 변경 불가능한 클래스를 만들어야 함
- JPA 스펙상 엔티티나 인베디드 타입은 자바 기본 생성자를
public
또는 protected
로 설정해야 함
설계한 그대로 테이블 생성 완료
강의 : 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발