[Java Spring] 4. 도메인 모델과 테이블 설계

Hayoon·2022년 7월 10일
0


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) 편의성을 위해서 사용.)

모든 연관관계는 Lazy Loading으로 설정

즉시로딩( 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

profile
Junior Developer

0개의 댓글