요구사항
- 회원은 상품을 주문할 수 있다.
- 주문 시 여러 종류의 상품을 선택할 수 있다.
기능 목록
도메인 모델 분석
- 회원과 주문의 관계: 회원은 여러 번 주문이 가능하다.
- 주문과 상품의 관계: 주문할 때 여러 상품을 선택할 수 있다. 반대로 각 상품은 여러 번 주문될 수 있다.
- 주문 상품이라는 모델을 만들어 다대다 관계를 일대다, 다대일 관계로 풀어낸다.
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| @Entity
public class Member {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "MEMBER_ID")
private Long id;
private String name;
private String city;
private String street;
private String zipcode;
//Getter, Setter...
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| @Entity
public class Item {
@Id @GeneratedValue
@Column(name = "ITEM_ID")
private Long id;
private String name;
private int price;
private int stockQuantity;
//Getter, Setter...
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| @Entity
@Table(name = "ORDERS")
public class Order {
@Id @GeneratedValue
@Column(name = "ORDER_ID")
private Long id;
@Column(name = "MEMBER_ID")
private Long memberId;
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus status;
//OrderStatus는 Order, Cancel로 구성된 Enum 클래스.
//Getter, Setter...
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| @Entity
public class OrderItem {
@Id @GeneratedValue
@Column(name = "ORDER_ITEM_ID")
private Long id;
@Column(name = "ORDER_ID")
private Long orderId;
@Column(name = "ITEM_ID")
private Long itemId;
//Getter, Setter...
}
|
문제점
만약 어떠한 주문을 조회한다고 치자.
1
| Order order = em.find(Order.class, 1L);
|
이 order를 한 고객을 조회하려면 어떻게 해야 할까?
1
2
3
| Long memberId = order.getMemberId();
Member member = em.find(Member.class, memberId);
|
이렇게 memberId를 조회하는 과정을 거치면서 객체지향스럽지 않은 코드가 나타나게 된다.
정리하면 아래와 같다.
- 현재의 방식은 객체 설계를 객체가 중심이 아닌 테이블 설계에 맞춘 방식이다.
- 테이블의 외래키를 객체에 그대로 가져왔다.
- 객체를 참조로 객체 그래프로 탐색하는 것이 아닌 하나하나 조회해가며 번거롭게 조회해야 한다.
- 참조가 없으므로 위의 UML도 잘못되었다.
이러한 부분을 연관관계 매핑을 통해 해결한다.