- 도메인이란?
- 비즈니스적인 어떤 업무 영역과 관련
고객이 음식을 주문하는 과정, 주문받은 음식을 처리하는 과정, 배달 과정 등 도메인 지식들을 서비스 계층에서 비즈니스 로직으로 구현해야 하는 것- 우리가 실제로 현실 세계에서 접하는 업무의 한 영역
- 애그리거트(Aggregate)
- 업무 도메인들의 묶음 ex) 회원 애그리거트, 주문 애그리거트, 음식 애그리거트, 결제 애그리거트
- 비슷한 범주의 연관된 업무들을 하나로 그룹화 해놓은 그룹
- 애그리거트 루트(Aggregate Root)
- 하나의 애그리거트를 대표하는 도메인
✔ 애그리러트 루트 선정 기준
다른 모든 도메인들과 직간접적으로 연관이 되어 있는 도메인
애그리거트 루트의 기본키 정보를 다른 도메인들이 외래키 형태로 가지고 있다.
- 도메인에서 애그리거트 루트 찾기
- 회원 (애그리거트)
- 회원 정보 (애그리거트 루트)
- 주문 (애그리거트)
- 주문 정보 (애그리거트 루트)
- 주문 커피 정보
- 커피 (애그리거트)
- 커피 정보 (애그리거트 루트)
- 애그리거트 간의 관계
- 회원 정보(Member)와 주문 정보(Orders)의 관계 (1대N)
- 한 명의 회원은 여러 번 주문을 할 수 있다.
- 주문 정보와 커피 정보의 관계 (N대N)
- 하나의 주문은 여러 종류의 커피를 가질 수 있다.
- 하나의 커피는 여러 건의 주문에 속할 수 있다.
- N 대 N의 관계는 일반적으로 1대N, N대1의 관계로 재 설계
- 주문 정보와 주문 커피 정보 (Order_Coffee) : 1대N
- 주문 커피 정보(Orders_Coffee)와 커피 정보: N대1
- 엔티티 클래스 간의 관계
- 회원(Member) 엔티티 클래스
- Member 클래스와 Order의 관계는 1대N의 관계이기 때문에
List<Order>
가 추가- 한 명의 회원은 여러 건의 주문 가능.
List<Order>
멤버 변수 추가- 주문(Order) 엔티티 클래스
- Order클래스와 Coffee 클래스는 N대N, 1대N 의 관계로 만들어 주는
List<OrderCoffee>
를 멤버 변수로 추가- 커피(Coffee) 엔티티 클래스
- N대N의 관계를 1대 N의 관계로 만들어주는
List<OrderCoffee>
를 멤버 변수로 추가- 주문_커피(OrderCoffee) 클래스
- Order 클래스와 Coffee 클래스의 N대N 관계를 1대N 으로 각각 만들어 주기 위한 클래스
- 주문하는 커피가 한 잔 이상일 수 있기 때문에 quantity(주문수량) 멤버 변수 추가
- 데이터베이스 테이블 설계
- 도메인 엔티티 클래스간의 관계는 객체의 참조, 테이블간의 관계는 외래키 참조로 이루어짐.
- 애그리거트 객체 매핑 규칙
- 모든 엔티티 객체의 상태는 애그리거트 루트를 통해서만 변경할 수 있다.
- 하나의 동일한 애그리거트 내에서의 엔티티 객체 참조
- 동일한 하나의 애그리거트 내에서는 엔티티 간에 객체로 참조한다.
- 애그리거트 루트 대 애그리거트 루트 간의 엔티티 객체 참조
- 애그리거트 루트 간의 참조는 객체 참조 대신에 ID로 참조한다.
- 1대1과 1대N관계일 때는 테이블 간의 외래키 방식과 동일
- N대N 관계일 때는 외래키 방식인 ID참조와 객체 참조 방식이 함께 사용된다.
✔ Member 클래스와 Order 클래스의 애그리거트 루트 매핑
- memberId 변수에
@Id
애너테이션 추가 식별자로 지정
데이터베이스 테이블에서 MEMBER 테이블과 매핑된다.
- (1)과 같이
@Table
애너테이션을 추가하지 않으면 클래스명이 테이블의 이름과 매핑,
(Order 단어는 SQL쿼리문에서 사용하는 예약어이기 때문에) 테이블 이름 ORDERS로 변경- (2) 식별자로 지정, ORDERS 테이블과 매핑된다.
- (3) Member 클래스는 회원 애그리거트의 루트
Order 클래스는 주문 애그리거트의 루트
Member 클래스와 Order 클래스는 1대N의 관계
매핑규칙 (3) 번에서 애그리거트 루트 간에는 객체로 직접 참조가 아니라 ID로 참조
AggergateReference
클래스로 Member 클래스를 감싸면 직접적인 객체참조가 아닌 ID참조✔ Order 클래스와 Coffee 클래스의 애그리거트 루트 매핑
- N대N의 관계
- (1)
@Id
애너테이션을 붙여 식별자 지정, COFFEE 테이블과 매핑됨.- (2) Coffee의 중복 등록을 체크하기 위해 필요한 coffeeCode 멤버 변수 추가
- (1) 애그리거트 루트 매핑규칙으로 ID값을 참조하나 조금 다른 방식
CoffeeRef
클래스로 서로 1대N 관계로 풀어줄 엔티티CoffeeRef
클래스는 주문 애그리거트에 포함된 주문커피정보 엔티티의 역할을 하는데 중요한건 이 엔티티가 Order클래스와 동일한 애그리거트에 있다.
- 동일한 애그리거트 내에서는 객체 참조를 사용
Set<CoffeeRef>
를 통해Order
클래스와 주문커피정보 엔티티 역할을 하는CoffeeRef
클래스와 1대N 의 관계를 만들 수 있다.
@MappedCollection
애너테이션의 역할@MappedCollection(idColumn = "ORDER_ID", keyColumn = "ORDER_COFFEE_ID") //(1) private List<CoffeeRef> orderCoffees = new ArrayList<>();
- (1) 은 엔티티 클래스 간에 연관 관계를 맺어주는 정보를 의미
idColumn
애트리뷰트는 자식 테이블에 추가되는 외래키에 해당되는 컬럼명 지정keyColumn
애트리뷰트는 외래키를 포함하고 있는 테이블의 기본키 컬럼명 지정@MappedCollection
애너테이션을 추가하는 필드의 타입이 List일 경우에는 keyColumn값 입력 필수, Set은 필수 아님
- (1) 테이블 이름 변경
- (2) CoffeeRef 클래스는 주문 애그리거트 내에 있는 엔티티 클래스
COFFEE 클래스는 커피 애그리거트 내에 있는 엔티티 클래스이자 애그리거트 루트
N대N 관계에서는AggregateReference
로 감쌀 필요가 없다.✔ Order 클래스의 멤버 변수 추가
- (1) 주문 상태 정보
- 주문 상태 정보를 나타내는 멤버 변수이며, OrderStatus enum 타입
주문 정보가 저장될 때 기본 값은ORDER_REQUEST (주문요청)
- (2) 주문 등록 시간
- 주문이 등록되는 시간 정보를 나타내는 멤버 변수,
LocalDateTime
타입- (3) OrderStatus enum
주문의 상태를 나타내는 enum
(주문을 위한 전용 상태값으로 Order 클래스의 멤버로 포함되어있음)✔ 테이블 생성 스크립트 추가
- 인메모리 DB 사용하기 때문에 별도의 테이블 DROP 과정은 필요없음.