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