엔티티 개발
엔터티 클래스를 작성할 때 게터를 열어 둡니다. 필요할 때만 세터 사용.
변경 지점이 명확하도록 변경에 대한 별도의 비즈니스 방법을 제공합니다.
기본적으로 단방향 매핑이 수행되며,
범주 < -> 항목은 ManyToMany로 계속 학습합니다. 실제로는 ManyToMany를 사용하지 마십시오.
기본적으로 Global Fetch 전략은 Lazy로 설정되지만 필요한 경우 Eager로 설정됩니다.
포함된 값 유형값 유형인 주소를 설명하려면 기본적으로 변경 불가능해야 합니다.
setter가 아닌 생성자를 통해 원래 값을 변경할 수 없게 만들고,
보다 안전한 설계를 위해 @NoArgsConstructor 대신 기본 생성자의 액세스 한정자를 Protected로 설정합니다.
회원
@Entity @Getter
public class Member {
// PK
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "member_id")
private Long id;
@Column
private String name;
@Embedded
@Column
private Address address;
}
명령
@Entity @Getter
@Table(name = "orders")
public class Order {
// PK
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "order_id")
private Long id;
// 멤버와 주문은 1:N으로 단방향 매핑
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
// 주문은 배송과 1:1 관계이다
// 1:1 관계에서 Access가 더 많은 쪽을 키의 주인으로 지정했음
// 주문을 볼때 배송정보가 무조건 필요하니 FetchType은 즉시 전략을 사용한다
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "delivery_id")
private Delivery delivery;
// 주문 시간
@Column
private LocalDateTime orderDate;
// 주문의 상태 필드 (ORDER, CANCEL)
@Enumerated(EnumType.STRING)
private OrderStatus status;
}
기사
@Entity @Getter
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // 상속관계 매핑 전략 지정
@DiscriminatorColumn(name = "dtype") // 하위 클래스에 @DiscriminatorValue 지정해줘야함
public abstract class Item {
// PK
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "item_id")
private Long id;
// 상품 이름
@Column
private String name;
// 상품 가격
@Column
private int price;
// 상품 수량
@Column
private int stockQuantity;
// 다대다 매핑
@ManyToMany(mappedBy = "items")
private List<Category> categories = new ArrayList<>();
}
주소
/* 임베디드 값 타입 클래스 */
@Embeddable
@Getter
public class Address {
@Column
private String city;
@Column
private String street;
@Column
private String zipCode;
public Address(String city, String street, String zipCode) {
this.city = city;
this.street = street;
this.zipCode = zipCode;
}
protected Address() {}
}
주문 항목
/* 주문과 상품을 이어주는 조인 테이블 */
@Entity @Getter
public class OrderItem {
// PK
@Id @GeneratedValue
@Column(name = "order_item_id")
private Long id;
// 상품과 주문상품은 1:N 관계로 단방향 매핑
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id")
private Item item;
// 주문과 주문상품은 1:N 관계로 단방향 매핑
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id")
private Order order;
// 주문 가격
@Column
private int orderPrice;
// 주문 수량
@Column
private int count;
}
배달
@Entity @Getter
public class Delivery {
// PK
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "delivery_id")
private Long id;
// 배송과 주문은 1:1 관계이다
@OneToOne(mappedBy = "delivery")
private Order order;
// 임베디드 값 타입
@Embedded
private Address address;
// 배송 상태 (READY, COMP)
@Enumerated(EnumType.STRING)
private DeliveryStatus status;
}
범주
@Entity @Getter
public class Category {
// PK
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "category_id")
private Long id;
// 카테고리 이름
@Column
private String name;
// 다대다는 중간 테이블이 필요하므로 JoinTable로 만들어준다.
// joinColumns와 inverseJoinColumns는 조인테이블에 FK 컬럼을 만들어준다.
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "category_item",
joinColumns = @JoinColumn(name = "category_id"),
inverseJoinColumns = @JoinColumn(name = "item_id"))
private List<Item> items = new ArrayList<>();
// 카테고리의 계층 구조를 위한 Self 양방향 연관관계 매핑
@ManyToOne
@JoinColumn(name = "parent_id")
private Category parent;
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();
}
영화
@Entity @Getter
@DiscriminatorValue("M")
public class Movie extends Item {
@Column
private String director;
private String actor;
}
앨범
@Entity @Getter
@DiscriminatorValue("A")
public class Album extends Item {
@Column
private String artist;
@Column
private String etc;
}
책
@Entity @Getter
@DiscriminatorValue("B")
public class Book extends Item {
@Column
private String author;
@Column
private String isbn;
}
세다
public enum DeliveryStatus {
READY, COMP
}
public enum OrderStatus {
ORDER, CANCEL
}
결과표 확인
엔터티 클래스를 작성한 후 테이블이 H2 데이터베이스에 잘 배치되어 있는지 확인하십시오.