계층 간 변환 과정

 

 

 

 

 

 

 

 

배달 주문 앱의 도메인 세분화

 

👀애그리거트 루트(Aggregate Root) 선정 기준

애그리거트 내의 도메인들 중에서 다른 모든 도메인들과 직간접적으로 연관이 되어 있는 도메인

 

데이터베이스의 테이블 간 관계로 보자면, 애그리거트 루트는 부모 테이블이 되고, 애그리거트 루트가 아닌 다른 도메인들은 자식 테이블

즉, 애그리거트 루트(Aggregate Root)의 기본키 정보를 다른 도메인들이 외래키 형태로 가지고 있다고 볼 수 있다

 

 

 

관계형 데이터베이스에서 A 테이블의 기본키를 B 테이블이 가지고 있다면 A는 부모 테이블이 되고, B는 자식 테이블이 됩니다. B인 자식 테이블이 가지고 있는 A 테이블의 기본키를 외래키라고 함

 

 

📋샘플 애플리케이션 도메인 엔티티 및 테이블 설계

도메인에서 애그리거트 루트 찾기

Spring Data JDBC를 이용해서 구현해야 할 커피 주문 샘플 애플리케이션의 도메인 모델

 

 

 

 

 

 

📜애그리거트 간의 관계

  • 회원 정보(Member)와 주문 정보(Orders)의 관계(1 대 N)
    • 한 명의 회원은 여러 번 주문을 할 수 있다.
  • 주문 정보(Orders)와 커피 정보의 관계(N 대 N)
    • 하나의 주문은 여러 종류의 커피를 가질 수 있다
    • 하나의 커피는 여러 건의 주문에 속할 수 있다
  • N 대 N의 관계는 일반적으로 1 대 N, N 대 1의 관계로 재 설계 되기 때문에 아래와 같이 변경.
    • 주문 정보(Orders)와 주문 커피 정보(Order_Coffee): 1 대 N
    • 주문 커피 정보(Order_Coffee)와 커피 정보(Coffee): N 대 1

 

 

 

📜엔티티 클래스 간의 관계

 

이 애그리거트를 기준으로 도메인 엔티티 클래스 간의 관계를 나타내면 다음과 같다.

 

회원(Member) 엔티티 클래스

  • Member 클래스와 Order의 관계는 1 대 N의 관계이기 때문에 Member 클래스에List<Order> 가 추가

 

 

📌데이터베이스 테이블 간의 관계는 외래키를 통해 맺어지지만 클래스 간의 관계는 객체의 참조를 통해 맺어진다!

 

  • 주문(Order) 엔티티 클래스
    • Order 클래스와 Coffee 클래스는 N 대 N의 관계를 가지기 때문에 N 대 N의 관계를 1 대 N의 관계로 만들어주는 List<OrderCoffee>를 멤버 변수로 추가
  • 커피(Coffee) 엔티티 클래스
    • Coffee클래스와 Order 클래스는 N 대 N의 관계를 가지기 때문에 N 대 N의 관계를 1 대 N의 관계로 만들어주는 List<OrderCoffee>를 멤버 변수로 추가
  • 주문_커피(OrderCoffee) 테이블
    • Order 클래스와 Coffee 클래스가 N 대 N 관계이므로 두 클래스의 관계를 각각 1 대 N의 관계로 만들어주기 위한 OrderCoffee 클래스가 추가
    • 주문하는 커피가 한 잔 이상일 수 있기때문에 quantity(주문 수량) 멤버 변수를 추가

Spring Data JDBC 기술을 사용하기 위해서는 도메인 모델을 잘 정의하고 애그리거트 루트(Aggregate Root)를 찾아야 함

 

 

 

데이터베이스 테이블 설계

커피 주문 샘플 애플리케이션의 테이블 설계

 

도메인 엔티티 클래스 간의 관계는 객체의 참조로 이루어지지만 테이블 간의 관계는 외래키(Foreign key) 참조로 이루어짐

 

 

🔎객체 참조는 N인 클라스에서 리스트를 넣는다

🔎테이블 참조는 N인 곳에서 1인 테이블의 외래키를 참조한다 

 

 

Spring Data JDBC를 통한 데이터 액세스 계층 구현- 도메인 엔티티 클래스 정의

설계한 엔티티 클래스를 코드로 정의해보자

 

 

💡코드 구현 전 꼭 기억하기!

테이블의 외래키(Foreign key) vs 클래스의 객체 참조 리스트(List)

엔티티 설계 확인

Member 클래스와 Order 클래스는 1 대 N의 관계이다.
-1에 해당되는 Member 클래스는 N에 해당되는 Order 클래스의 객체를 참조할 수 있도록 List를 멤버 변수로 가진다.

Order 클래스와 Coffee 클래스는 N 대 N의 관계이므로, 1 대 N과, N 대 1의 관계로 변환되었다.
-1에 해당되는 Order 클래스는 N에 해당되는 OrderCoffee 클래스의 객체를 참조할 수 있도록 List를 멤버 변수로 가진다.
-1에 해당되는 Coffee 클래스는 N에 해당되는 OrderCoffee 클래스의 객체를 참조할 수 있도록 List를 멤버 변수로 가진다.

테이블 설계 확인


MEMBER 테이블과 ORDERS 테이블은 1 대 N의 관계이다.

-1에 해당되는 MEMBER 테이블과 N에 해당되는 ORDERS 테이블은 ORDERS에 추가된 member_id 외래키(Foreign key)로 조인할 수 있다.

ORDERS 테이블과 COFFEE 테이블은 N 대 N의 관계이므로, 1 대 N과 N 대 1의 관계로 변환되었다.
 
-1에 해당되는 COFFEE 테이블과 N에 해당되는 ORDER_COFFEE 테이블은 ORDER_COFFEE 테이블에 추가된 coffee_id 외래키(Foreign key)로 조인할 수 있다.

 

 

 

Spring Data JDBC에서의 애그리거트(Aggregate) 객체 매핑

 

데이터베이스 테이블의 경우 우리가 설계한 대로 테이블 스키마를 사용해서 테이블을 생성하면 된다.

그런데 문제는 도메인 엔티티 클래스이다.

 

도메인 엔티티 클래스 간의 관계는 잘 설계된게 맞지만 Spring Data JDBC를 사용하기 위해서는 우리가 설계한 도메인 엔티티 클래스의 관계를 DDD(Domain Driven Design, 도메인 주도 설계)의 애그리거트(Aggregate) 매핑 규칙에 맞게 한번 더 변경할 필요가 있다.

 

📌애그리거트 객체 매핑 규칙

(1) 모든 엔티티 객체의 상태는 애그리거트 루트를 통해서만 변경할 수 있다.

(2) 하나의 동일한 애그리거트 내에서의 엔티티 객체 참조
 -동일한 하나의 애그리거트 내에서는 엔티티 간에 객체로 참조한다.

(3) 애그리거트 루트 대 애그리거트 루트 간의 엔티티 객체 참조
 -애그리거트 루트 간의 참조는 객체 참조 대신에 ID로 참조한다.
-1대1과 1대N 관계일 때는 테이블 간의 외래키 방식과 동일하다.
-N대N 관계일 때는 외래키 방식인 ID 참조와 객체 참조 방식이 함께 사용된다.

💡N대 N의 관계를 코드로 구현 할 때 단계!

 

1. N대 N의 관계를 -> 1대 N, N대 1의 관계로 변경

 

2. 1대 N, N대 1의 관계를 CoffeeRef와 같이 중간에서 ID를 참조하게 해주는 클래스를 통해 다시 1대 N , N대 1의 관계로 변경

 

 

 

📝관계 총정리

 

 

복사했습니다!