개발소설

Spring Data JDBC 기반의 도메인 엔티티 클래스 정의 본문

Spring Framework

Spring Data JDBC 기반의 도메인 엔티티 클래스 정의

ChaeHing 2023. 4. 20. 03:10

DDD(Domain Driven Design)

  • 도메인 위주의 설계 기법

도메인(Domain)

  • 비즈니스적인 어떤 업무 영역
  • 비즈니스 업무 영역을 의미하는것은 도메인 지식이라고 부른다.
  • 도메인 지식들을 서비스 계층에서 비즈니스 로직으로 구현해야 한다.
  • 도메인 지식이 많을 수록  퀄리티높은 애플리케이션을 만들 가능성이 높다.

엔티티 클래스 설계

  • 데이터베이스 테이블 간의 관계는 외래키를 통해 맺어지고
  • 클래스끼리 관계는 객체의 참조를 통해 관계가 맺어진다.

애그리거트(Aggregate)

  • 비슷한 업무의 하위 수준 도메인들의 묶음

애그리거트 루트(Aggregate Root) 

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

 

 

애그리거트 객체 매핑 규칙

 

  1. 모든 엔티티 객체의 상태는 애그리거트 루트를 통해서만 변경할 수 있다.
    • 도메인 규칙에 대한 일관성 유지
    • 음식이 다 만들어지기 전까지만 주문 취소나 변경을 할 수 있음
  2. 하나의 동일한 애그리거트 내에서의 엔티티 객체 참조
    • 동일한 하나의 애그리거트 내에서는 엔티티 간에 객체로 참조한다 
  3. 애그리거트 루트 대 애그리거트 루트 간의 엔티티 객체 참조
    1. 애그리거트 루트 간의 참조는 객체 참조 대신에 ID로 참조한다.
    2. 1대1과 1대 N 관계일 때는 테이블 간의 외래키 방식과 동일하다.
    3. N대 N 관계일 때는 외래키 방식인 ID 참조와 객체 참조 방식이 함께 사용된다.
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.Id;

@Getter
@Setter
public class Member {
		// (1)
    @Id
    private Long memberId;

    private String email;

    private String name;

    private String phone;
}
@Table("ORDERS")  //(1)
public class Order {
    
    private AggregateReference<Member, Long> memberId; // (2)
    
    @MappedCollection(idColumn = "ORDER_ID", keyColumn = "ORDER_COFFEE_ID") // (3)
    private Set<CoffeeRef> orderCoffees = new LinkedHashSet<>();
    
    ..
    
}
  • (1) @Table("테이블명")
    • 엔티티 클래스와 매핑할 테이블명
    • 해당 애너테이션을 사용하지 않으면 기본적으로 엔티티 클래스명이 테이블 명과 매핑
  • (2) AggregateReference 클래스는 다른 애그리거트 루트 간의 참조 역할
    • AggregateReference 클래스는 테이블의 외래키처럼 다른 객체의 ID 값을 참조할 수 있도록 해준다.
    • memberId는 Member 엔티티 클래스의 ID (pk)
    • Member 와 Order는 1:N 관계이며 애그리거트 루트 간의 참조 - ID로 참조 (외래키 방식)
  • (3) @MappedCollection는 엔티티 클래스 간에 연관 관계를 맺어준다.
    • Order와 Coffee가 N:N 관계
    • N:N 관계에서는  ID 참조와 객체 참조가 동시에
    • CoffeeRef는 N:N 관계를 1:N, N:1 관계로 풀어줄 엔티티 클래스 (참조테이블)
      • Order - CoffeeRef - Coffee
    • idColumn은 자식테이블의 추가 되는 외래키
      • Order의 pk, CoffeeRef의 외래키
    • keyColumn은 자식테이블의 기본키
      • CoffeeRef의 기본키
package com.codestates.order.entity;

import lombok.Builder;
import lombok.Getter;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;

@Getter
@Builder
@Table("ORDER_COFFEE")
public class CoffeeRef {
    @Id
    private long orderCoffeeId;
    private long coffeeId; // coffeeId를 외래키로
    private int quantity;
}
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.Id;

@Getter
@Setter
public class Coffee {
    @Id
    private long coffeeId;
    private String korName;
    private String engName;
    private int price;
    private String coffeeCode;  // 주문 코드 중복등록 확인용
}

 

Comments