엔티티 개발

엔티티 개발

엔터티 클래스를 작성할 때 게터를 열어 둡니다. 필요할 때만 세터 사용.

변경 지점이 명확하도록 변경에 대한 별도의 비즈니스 방법을 제공합니다.

기본적으로 단방향 매핑이 수행되며,
범주 < -> 항목은 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 데이터베이스에 잘 배치되어 있는지 확인하십시오.