코드스테이츠_국비교육/[Section3]

47.02_[Spring MVC] Spring Data JDBC_도메인 엔티티 클래스 정의_22.10.28

생각없이 해도 생각보다 좋다. 2022. 10. 30. 01:09

>클래스 간 관계 설정
: 데이터베이스 테이블 간 관계는 PK와 FK의 지정으로 서로의 관계를 설정할 수 있음.
: 클래스는 객체 내 변수(필드)를 선언하며 해당 변수가 다른 클래스를 참조하는 변수로 선언함으로써 관계를 설정한다.
: 주의할 것은 PK와 FK 로 관계를 연결할 때에는 1:N 관계에서 N의 입장이 1의 입장의 PK 를 FK로 갖지만, 객체의 참조 관계에서는 1:N관계에서 1의 입장이 N의 입장의 객체를 List, Set과 같은 자료구조(컬렉션)으로 참조하는 필드를 갖는다.
: 하지만 이 또한 어그리거트 루트 간 관계에서는 반대된다. 즉, 어그리거트 루트 간 참조는 DB table과 같다.

>Aggregate 객체 매핑하기
-규칙
1. 모든 엔티티 객체의 상태는 애그리거트 루트를 통해서만 변경할 수 있다.
: 엔티티 객체의 상태를 변경한다는 의미는 엔티티 객체의 필드의 변경이나 메서드의 호출을 의미한다.
: 즉, 애그리거트 루트가 아닌 엔티티 객체의 상태를 변경하기 위해서는 애그리거트 루트의 엔티티 객체를 통해서 변경해야 한다는 의미이다.
2. 하나의 동일한 애그리거트 내에서는 엔티티 간에 객체로 서로를 참조한다.
: 한 애그리거트 내에서의 엔티티 객체들의 관계는 참조 관계로 이루어진다는 의미.
3. 애그리거트 루트 대 애그리거트 루트 간의 엔티티 객체 참조는 객체 참조가 아닌 Id를 통해 참조하며, N 관계에서는 외래키 객체 참조 방식을 같이 사용한다.
//여기서 엔티티 클래스는 최하위 도메인을 의미한다.

>구현에 사용되는 용어 설명

@Id
Entity 객체 Id에 @Id 애너테이션을 붙이면 Entity 객체 이름을 가진 DB 테이블과 매핑이 된다. @Id가 붙은 Entity 객체의 Id 변수는 매핑된 DB 테이블의 PK와 매핑이 된다.

@Table("")
Entity 객체 전체에 붙이는 애너테이션으로, @Id를 통해 DB 테이블과 매핑할 때, @Table의 Attribute 값으로 제공된 문장열과 같은 DB 테이블과 매핑이 된다.

AggregateReference<1, 2>
다른 Aggregate Root와 '1:N' 관계를 갖을 때 사용하는 클래스이다.
Entity A와 Entity B가 1:N 관계일 때, B 내부에 AggregateReference 클래스를 이용하여 A의 Id를 참조하는 필드를 설정한다.
1번 제네릭 요소로 연결되는 Entity 객체(Aggregate Root 객체)를 넣고, 2번 제네릭 요소에는 참조하는 객체의 Id의 자료형을 넣는다.

N:N 관계 구현
DB Table이 N:N 관계일 때 Join Table을 만들어 1:N, N:1 관계로 바꾸어 관계를 맺는 방식을 사용했다. Entity 객체도 같은 방식을 사용한다.
둘 다 Aggregate Root 객체인 Entity A와 Entity B가 N:N 관계를 맺는 상황을 구현하면 아래와 같다.
(1) Aggregate Root 객체간 관계는 Id 참조로 관계를 맺는다는 세번째 규칙을 적용해야 한다. 하지만 N:N 관계이기에 이것만으로는 부족하다.
(2) A와 B사이에 매개를 하는 C Entity 객체를 생성한다. 그리고 DDD 설계 방식에 따라 C 또한 특정 Aggregate에 포함되어야 한다. 그리고 어디에 포함되느냐에 따라 달라지겠지만 여기서 C는 A Aggregate에 포함된다고 가정한다.
(3) A는 C와 같은 Aggregate에 있으므로, 2번 규칙에 따라 객체 참조를 통해 관계를 맺는다. B:C 는 1:N 관계이므로 B 내부에 List, Set 과 같은 자료구조로 여러개의 C 참조형을 갖는 필드를 생성한다.
(4) A에서 C를 참조하는 필드에는 @MappedCollection 애너테이션이 붙는다.
@MappedCollection 애너테이션은 A와 C의 관계를 맺어주는 정보를 명확히 하는 애너테이션이다. Attribute 값으로 idColumn 과 keyColumn을 줄 수 있는데, idColumn은 C가 갖는 FK(외래키) 값을 준다. 즉, A와 매핑된 DB table내의 id 컬럼명을 문자열로 제공한다. keyColumn은 C와 매핑된 DB table내의 id 컬럼명을 문자열로 제공한다. 만약 A 객체 내에서 C를 참조하기 위한 자료구조를 Set을 사용할 경우에는 keyColumn attribute를 제공하지 않아도 된다.
(5) 위의 내용들을 고려하고 아직 생성하지 않은 C 객체를 생성한다.
C는 따로 본인의 id를 갖지 않는다. 대신 @Table("")에 A__B를 연결짓는다는 의미의 문자열을 제공하여 해당 명칭의 DB Table(join table)과 매핑된다.
(6) 또한 특이점으로 C와 B는 N:1관계지만 C 내부에 AggregateReference를 사용하여 B의 id를 감싼 필드가 없다. 대신 그저 B의 id 필드가 그대로 존재한다. 이는 A내부에 있는 @MappedCollection 애너테이션과 연계되고, 겉으로는 A-C-B 처럼 보이지만 사실 A-B 형식으로 연결되게 된다.