스프링데이터 + JPA/웹 애플리케이션 개발

7. 엔티티 개발

sdafdq 2023. 11. 5. 12:35
@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<>();

}

@Getter는 좋은데, @Setter는 생각하면서 넣으셈. @Setter 필요한 곳만 넣는게 좋음. 애노테이션 안쓰고. 차라리 별도의 비즈니스 메소드를 넣는 게 좋음. private로 만들고 비즈니스 메소드에서 사용하든..

 

Address는 임베디드타입

@Embeddable
public class Address {
    private String city;
    private String street;
    private String zipcode;
}

 

양방향 연관관계인데, (기본적으로 연관관계의 주인은 다 쪽이기때문에, 일쪽이 가지고 있다는 것 자체가 양방향 연관관계임을 추측할 수 있음)

일쪽이기 때문에 다쪽에 매핑

 

 

@Entity(name = "orders")
public class Order {
    @Id @GeneratedValue
    @Column(name = "order_id")
    private Long id;

    @ManyToOne
    @JoinColumn(name = "member_id")
    private Member member;

    @OneToMany(mappedBy = "order")
    private List<OrderItem> orderItems = new ArrayList<>();

    @OneToOne
    @JoinColumn(name = "delivery_id")
    private Delivery delivery;

    private LocalDateTime orderDate;


    @Enumerated(EnumType.STRING)
    private OrderStatus status;

}

order라는 문자는 명령어 중에 order by가 있기에 db에 충돌이 있을 수 있어서 orders라고 함.

 

Member는 다대일, 다 쪽인 내가 연관관계 주인

 

OrderItem은 내가 일쪽이니 매핑됨.

 

일대일은 테이블 자체에서도 포링키를 누가 가지고 있어도 상관없음.

근데, 보통 Order를 통해 배송에 접근하지, 반대는 이상하기에 Order가 포링키를 가지고 또 주인이 됨.

OrderStatus는 enum타입인데, 저거 STRING으로 해 줘야 함. ORDINAL은 말 그대로 순서인데 추가될 경우 조금 곤란한 경우가 있음. 그냥 STRING이 정확함.

 

public enum OrderStatus {
    ORDER, CANCCEL
}

 

 

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

Item과 내가 다 쪽이니 주인

 

Order도 내가 다 쪽이니 주인.

 

@JoinColumn 해서 포링키도 써주고

 

왜 int타입으로 했는지 모르겠네. Integer가 아니라.

 

 

 

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@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;
}

이거는 직접 Item 자체를 생성할 건 아니라서 가상클래스로 함

@Inheritance 직역은 계승인데, 전략을 싱글테이블 전략으로 함.

@DiscriminatorColumn이 직역은 판별자 열 인데, 그 열이름을 dtype이라고 함. 기본이 dtype 이긴 함.

 

@Entity
@DiscriminatorValue("Album")
@Getter @Setter
public class Album extends Item{
    private String artist;
    private String etc;
}

 

@DiscriminatorValue 직역은 판별자 값인데, Album으로 함. 그럼 DB의 판별자열에 값으로 Album 찍힘.

기본이 Entity 이름이라 Album이긴 함.

 

@Entity
@DiscriminatorValue("Book")
@Getter @Setter
public class Book extends Item{
    private String author;
    private String isbn;
}

 

@Entity
@DiscriminatorValue("Movie")
@Getter @Setter
public class Movie extends Item{
    private String director;
    private String actor;
}

 

 

 

 

@Entity
public class Delivery {
    @Id @GeneratedValue
    @Column(name = "delivery_id")
    private Long id;

    @Embedded
    Address address;

    @OneToOne(mappedBy = "delivery")
    private Order order;

    @Enumerated(EnumType.STRING)
    private DeliveryStatus status;
}

 

 

public enum DeliveryStatus {
    READY, COMP
}

 

 

 

 

참고로 JPA 스펙 상 엔티티나 임베디드는 기본생성자(인자 아무것도 안받는, 비어있는)가 있어야 함.

public 또는 protected로 설정을 해야 하는데, 보통 protected로 하면 됨. 빈 생성자를 직접 생성할 일은 아마 없을 것 같으니..

 

 

'스프링데이터 + JPA > 웹 애플리케이션 개발' 카테고리의 다른 글

9. 엔티티 개발 주의점  (0) 2023.11.05
8. 엔티티 개발 2  (0) 2023.11.05
6. 도메인 모델과 테이블 설계  (0) 2023.11.04
5. 요구사항 분석  (0) 2023.11.04
4. DB(H2) 설치 및 설정  (0) 2023.11.04