1.4 연관관계 맵핑 분석

회원과 주문

-회원도 오더로 갈 수 있고, 오더도 회원으로 갈 수 있도록 설계 했다.(양방향 연관관계)

-일대다 , 다대일의 양방향 관계다. 따라서 연관관계의 주인을 정해야 한다.

 관계형데이터베이스에서는 1대 다의 관계에서는 다에 무조건 외래키가 있게 된다.

 외래 키가 있는 주문을 연관관계의 주인으로 정하는 것이 좋다.

 그러므로 ORDERS 엔티티에 있는 MEMBER가 연관관계의 주인이 되고,

 MEMBER엔티티의 ordersmapped by로 단순 읽기만 가능한 연관관계의 거울 즉 단순

 조회용으로만 이용한다.

-연관관계의 주인쪽에 값을 세팅해야 값이 변경된다.

 거울쪽값은 단순조회용이다.

 

-일대다, 다대일의 양방향 관계다. 따라서 연관관계의 주인을 정해야 하는데,

 외래 키가 있는 주문을 연관관계의 주인으로 정하는 것이 좋다.

 그러므로 Order.memberORDERS.MEMBER_ID 외래 키와 매핑한다.

 

*쉽게 얘기하면 주문이 한 개만 있는 것이 아니라 많아질 수 있다고 할 때에

주문쪽에서 PK생성으로 멤버를 참조하여야 하므로 1(MEMBER) (ORDERS)의 관계라고

할 수 있다. 주문측이 갑, 주인이 된다.

 

주문상품과 주문

-한번 주문할 때 주문수량과 주문수량에 따라 가격이 달라질 수 있기 때문에

 주문상품을 두게 된다.

-다른 사람이 주문한 정보가 주문상품에 있을 수 없다.

 주문한상품들이(OrderItem)에는 주문할 때 하나의 Order에만 연관관계가 걸린다.

 주문상품들의 정보들이 OrderItem : List에 오게 된다.

 그래서 다대(ORDERS_ITEM)1(ORDERS)관계가 된다.

 

->다대일 양방향 관계다. 외래 키가 주문상품에 있으므로 주문상품이 연관관계의 주인이다.

   그러므로 OrderItem.orderORDER_ITEM.ORDER_ID 외래 키와 매핑한다.

 

*연관관계 매핑 분석할 때에

-서비스의 특성과 일반적인 관계를 알고, 일반적으로 접근해볼 것

-외래키가 있는 곳이 연관관계의 주인

 

주문상품과 상품

-itemorderitem에서 의 정보를 맵핑 할 것이 없다.

-나를 주문한 orderitem을 찾아 할필요가 없고,

 orderitem을 찾고 싶을 때에 루트를 orderitem으로 쿼리를 찍으면 된다.

 즉, orderitem에서 item정보만 잘 맵핑해주면 된다.

->다대일 단방향 관계다. OrderItem.itemORDER_ITEM.ITEM_ID 외래 키와 매핑한다.

   주문과 배송

-일대일 양방향 관계다. Order.deliveryORDERS.DELIVERY_ID 외래 키와 매핑한다.

-주문정보에 배송정보가 들어가고 OrdersDelivery_ID(PK)가 넣어 두었다.

 

-DELIVERY_ID가 있는 외래키와 매핑하면 Orders가 연관관계의 주인이 된다.

 

카테고리와 상품

-@ManyToMany를 사용해서 매핑한다.

 (실무에서 @ManyToMany는 사용하지 말자. 여기서는 다대다 관계를 예제로 보여주기 위

 해 추가했을 뿐이다)

-편법이 아닌 정상적인 방법으로는 테이블관계는 ManyToMany로 표현할 수 있는 방법이

 없기 때문에, CATEGORY_ITEM 중간테이블로 풀어낸다..

 

카테고리와 상품관련하여 앞에서의 내용과 같은 내용

-객체에서는 카테고리가 아이템리스트를 가져도 되고

 아이템이 카테고리리스트를 가져도 된다.

 양쪽 컬렉션을 만들면 객체는 다대 다로 만들 수 있지만

 관계형데이터베이스는 일반적 설계로는 그렇게 할 수 없다.

 중간에 매핑 테이블(CATEGORY_ITEM)을 두어,

1(CATEGORY) (CATEGORY_ITEM) 관계 및 다대(CATEGORY_ITEM) 1(ITEM)로 풀어

낸다.

 

참고

-외래 키가 있는 곳을 연관관계의 주인으로 정해라.

 연관관계의 주인은 단순히 외래 키를 누가 관리하냐의 문제이지 비즈니스상 우위에 있다고

 주인으로 정하면 안된다..

-예를 들어서 자동차와 바퀴가 있으면, 일대다 관계에서 항상 다쪽에 외래 키가 있으므로

 외래 키가 있는 바퀴를 연관관계의 주인으로 정하면 된다.

 

주의 (연관관계를 잘못 설정하게 되면 생기는 현상)

-물론 자동차를 연관관계의 주인으로 정하는 것이 불가능 한 것은 아니지만,

 자동차를 연관관계의 주인으로 정하면 자동차가 관리하지 않는 바퀴 테이블의 외래 키 값이

 업데이트 되므로 관리와 유지보수가 어렵고, 추가적으로 별도의 업데이트 쿼리가 발생하는

 성능 문제도 있다. 자세한 내용은 JPA 기본편을 참고하자.

 

1-2. 회원 엔티티 분석

1.회원(Member)엔티티

 

회원(Member)

id: Long

-회원엔티티에 공통속성은 id가 다 있다.

-id=pk generating 해주는 id값 데이터베이스

 pk(id)long 값으로 해놓았다.

 

name: String

-이름(string)

 

address: Address

-임베디드 타입(내장값타입)인 주소(Address : 설계도 하기 그림참고-value type address)

 

orders : List

-그리고 주문(orders) 리스트를 가진다.

 

2.주문 엔티티

 

주문(Order)

id

member : Member(회원정보)

orderItems : list (주문목록)

delivery : Delivery(배송정보)

orderDate : Date(주문한날짜)

status : OrderStatus(주문상태-주문,취소 등등)

 

-한 번 주문시 여러 상품을 주문할 수 있으므로 주문과 주문상품(OrderItem)은 일대다 관계 다.

-주문은 상품을 주문한 회원과 배송 정보, 주문 날짜, 주문 상태(status)를 가지고 있다.

-주문 상태는 열 거형을 사용했는데 주문(ORDER), 취소(CANCEL)을 표현할 수 있다.

 

3.주문상품 엔티티

 

주문상품(OrderItem)

-주문한 상품 정보와 주문 금액(orderPrice), 주문 수량(count) 정보를 가지고 있다.

 (보통 OrderLine, LineItem 으로 많이 표현한다.)

-주문상품을 추가한 다른 이유는 한번 주문시 여러 개의 상품을 담을 수 있는데

 주문시점시 주문한 상품의 개수 및 주문한 상품 가격정보가 필요하기 때문이다.

 

4.배송 엔티티

 

배송(Delivery)

id

order : order(주문정보, 배송지주소 아님)

address : Address(배송지주소-value type 값타입 주소를 재활용)

status : DeliveryStatus(배송현황)

 

-배송(Delivery): 주문시 하나의 배송 정보를 생성한다. 주문과 배송은 일대일 관계다.

-주문시 하나의 배송 정보를 생성한다. 주문과 배송은 일대일 관계다.

 

5.상품엔티티

 

상품(Item)

id

name (상품이름)

price: int (상품가격)

stockQuantity (상품재고)

categories: List(어느 카테고리에 매핑 되어 있는지에 대한 정보)

 

상품엔티티와의 상속관계

-상속관계Album, Book, Movie들이 있고,

 개별속성들이 상속관계로 다음과 같이 표현되어 있다.

Album - artist, etc

Book - author, isbn

Movie - director, actor

 

-이름, 가격, 재고수량(stockQuantity)을 가지고 있다.

 상품을 주문하면 재고수량이 줄어든다.

 상품의 종류로는 도서, 음반, 화가 있는데 각각은 사용하는 속성이 조금씩 다르다.

 

6. 카테고리엔티티

 

카테고리(Category)

id

name

items: List(카테고리가 가지고 있는 리스트)

parent: Category

(계층구조로 되어 있다. 내 부모가 누구인데, 자식(속성)은 여러개의 구조로 되어 있다라는 형태, 부모는 한개)

child: List

 

-카테고리(Category): 상품과 다대다 관계를 맺는다. parent, child로 부모, 자식 카테고리를

 연결한다.

 

7. 주소엔티티

 

주소(Address)

-값 타입(임베디드 타입)이다. 회원과 배송(Delivery)에서 사용한다.

 

 

설계구성도는 JPA에서 다룰 수 있는 모든관계개념들을 모두 넣어두었다.

1. MemberOrder - 1대 다 관계

2. Orderdelivery - 11 관계

3. OrderOrderItem - 1대 다 관계

4. OrderItemItem - 다대 1 관계

5. ItemAlbum,Book,Movie - 상속관계

6. CategoryItem - 다대 다 관계

 

실무에서 사용하기 애매한 것들

-Categoryitem의 다대 다 관계(JPA@다대다관계)는 실제운영에서 사용하면 안된다.

 1대 다 또는 다대 1 관계로 풀어내야 한다.

-MemberOrder 1대 다 관계가 아닌, 시스템적으로는 동등한 관계로 보고 고민해야 한다.

-회원을 통해서 주문이 일어난다가 아니라, 주문을 생성할 때 Member가 필요하다라고 생각을 해야 한다.

-쿼리가 일어날 때도 주문 내역이 필요할 때 멤버를 찾아서 거기에 있는 주문 리스트를 가져 오는 것이 아니라,

 order에서도 필터링 조건에 멤버가 들어간다.

-그래서 사실상 1대 다의 컬렉션은 필요없다..

 자세한 것은 기본편강의에서 다루었다.

 

참고

회원이 주문을 하기 때문에, 회원이 주문리스트를 가지는 것은 얼핏 보면 잘 설계한 것 같지만,

객체 세상은 실제 세계와는 다르다. 실무에서는 회원이 주문을 참조하지 않고, 주문이 회원을 참조하는 것으로 충분하다. 여기서는 일대다, 다대일의 양방향 연관관계를 설명하기 위해서 추가했다.

+ Recent posts