SEB_BE 47일차 - JDBC 기반 데이터 액세스 계층2

subimm_·2022년 10월 28일
0

코드스테이츠

목록 보기
47/83

💡 오늘의 학습목표

  • Spring Data JDBC 기반 도메인 엔티티 및 테이블 설계
  • Spring Data JDBC 데이터 액세스 계층 구현 - 도메인 엔티티 클래스 정의

📔 Spring Data JDBC 기반의 도메인 엔티티 및 설계

📖 DDD(Domain Driven Design)

  • 도메인 주도 설계
    Spring Data JDBC 와 밀접한 관련이 있다.
  • 도메인이란?
    • 비즈니스적인 어떤 업무 영역과 관련
      고객이 음식을 주문하는 과정, 주문받은 음식을 처리하는 과정, 배달 과정 등 도메인 지식들을 서비스 계층에서 비즈니스 로직으로 구현해야 하는 것
    • 우리가 실제로 현실 세계에서 접하는 업무의 한 영역
  • 애그리거트(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(주문수량) 멤버 변수 추가
  • ORM - 객체와 테이블을 매핑하는 기술 (클래스간의 연관 관계를 찾아야함)
  • 데이터베이스 테이블 설계
  • 도메인 엔티티 클래스간의 관계는 객체의 참조, 테이블간의 관계는 외래키 참조로 이루어짐.

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

📖 Spring Data JDBD에서의 애그리거트 객체 매핑

  • Spring Data JDBD를 사용하기 위해서 설계한 도메인 엔티티 클래스의 관계를 DDD의 애그리거트 매핑 규칙에 맞게 변경해야함.
  • 애그리거트 객체 매핑 규칙
  1. 모든 엔티티 객체의 상태는 애그리거트 루트를 통해서만 변경할 수 있다.
  2. 하나의 동일한 애그리거트 내에서의 엔티티 객체 참조
    • 동일한 하나의 애그리거트 내에서는 엔티티 간에 객체로 참조한다.
  3. 애그리거트 루트 대 애그리거트 루트 간의 엔티티 객체 참조
    • 애그리거트 루트 간의 참조는 객체 참조 대신에 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 과정은 필요없음.
profile
코린이의 공부 일지

0개의 댓글