Order<->Member은 양방향(1:N), Order<->Delivery은 양방향(1:1), Order<->OrderItem은 양방향(1:N), OrderItem->Item은 단방향(N:1), Category<->Item은 양방향(N:M)으로 설계된다.
Album, Book, Movie는 Item과 상속관계로, Item은 추상클래스로 구현한다.
@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")
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "delivery_id")
private Delivery delivery;
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus status; //주문상태, [ORDER, CANCLE]
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);
}
}
@Entity 어노테이션은 데이타베이스의 테이블과 일대일로 매칭되는 객체 단위이며 Entity 객체의 인스턴스 하나가 테이블에서 하나의 레코드 값을 의미한다. 객체의 인스턴스를 구분하기 위한 유일한 키값을 가지는데 이것은 테이블 상의 Primary Key 와 같은 의미를 가지며 @Id 어노테이션으로 표기.
@Getter @Setter은 Lombok으로 사용되며, 실무에서는 @Setter 사용을 제한한다. (변경 시, 추적이 어려우므로) Foreign Key를 가지는 테이블을 연관관계 주인으로 설정한다. N:1에서 N이 연관관계 주인이 됨.
//Order Class
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
ORDERS 테이블에서 Member_id를 외래키로 가지고 있으므로 연관관계 주인으로 설정된다.
//Member Class
@OneToMany(mappedBy = "member")
private List<Order> orders = new ArrayList<>();
MEMBER 테이블에서 mappedBy = "member"는 양방향 연관관계일때 반대쪽에 매핑되는 엔티티의 필드값을 준다.
@ManyToMany는 중간테이블 컬럼 추가할 수가 없고, 실무에서 사용이 어렵다. 따라서 @ManyToOne<->@OneToMany로 매핑해서 사용을 권한다.
Address도메인은 생성자에서 값을 모두 초기화하여 변경이 불가능하도록 하는 클래스이다. 따라서 @Embedded Annotation을 이용한다. @Setter을 제한하고, 기본생성자를 이용(또는 @RequiredArgsConstructor)를 사용한다.(이 어노테이션은 초기화 되지않은 final 필드나, @NonNull 이 붙은 필드에 대해 생성자를 생성해 줍니다. 주로 의존성 주입(Dependency Injection) 편의성을 위해서 사용.)
즉시로딩( EAGER )은 예측이 어렵고, 어떤 SQL이 실행될지 추적하기 어렵다. 특히 JPQL을 실행할 때 N+1 문제가 자주 발생한다.
실무에서 모든 연관관계는 지연로딩(LAZY)으로 설정해야 한다.
@XToOne(OneToOne, ManyToOne)관계는 기본이 즉시로딩이므로 직접 지연로딩으로 설정해야 한다.
(DB/Table 연관관계처럼 도토리도 단방향에서 양방향이 되었음 좋겠다.)
출처: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/unit/24284?tab=community&q=586008