Chapter 4 리포지터리와 모델 구현
4.1 JPA를 이용한 리포지터리 구현
∘ 자바의 ORM 표준인 JPA를 이용해서 리포지터리와 애그리거트를 구현하는 방법
4.1.1 모듈 위치
∘ 리포지터리 인터페이스는 애그리거트와 같이 도메인 영역에 속함
∘ 리포지터리를 구현한 클래스는 인프라스트럭처 영역에 속함
4.1.2 리포지터리 기본 기능 구현
∘ 리포지터리가 제공하는 기본 기능
- ID로 애그리거트 조회하기 : findBy프로퍼티이름(프로퍼티 값)
- 애그리거트 저장하기 : save()
∘ JPA는 트랙잭션 범위에서 변경한 데이터를 자동으로 DB에 반영
∘ 애그리거트를 삭제하는 기능을 만들 수 있음
4.2 스프링 데이터 JPA를 이용한 리포지터리 구현
∘ 스프링 데이터 JPA는 지정한 규칙에 맞게 리포지터리 인터페이스를 정의하면 리포지터리를 구현한 객체를 자동으로 만∘ 들어 스프링 빈으로 등록함 (다음 규칙을 따르는 인터페이스)
- org.srpingframework.data.repository.Repository<T,ID> 인터페이스 상속
- T는 엔티티 타입을 지정하고 ID는 식별자 타입을 지정
∘ 스프링 데이터 JPA 규칙에 맞는 메서드
- 리포지터리를 기준으로 저장하는 메서드
- 특정 프로퍼티를 이용해서 엔티티 조회
- 중첩 프로퍼티
4.3 매핑 구현
4.3.1 엔티티와 밸류 기본 매핑 구현
∘ 애그리거트 루트는 엔티티이므로 @Entity로 매핑 설정
∘ 한 테이블에 엔티티와 밸류 데이터가 같이 있으면 밸류는 @Embeddable로, 밸류 타입 프로퍼티는 @Embedded로 매핑 설정
∘ @AttributeOverride 애너테이션으로 칼럼 이름 변경
4.3.2 기본 생성자
∘ 엔티티와 밸류의 생성자는 객체를 생성할 때 필요한 것을 전달받음
∘ JPA에서 @Entity와 @Embeddable로 클래스를 매핑하려면 기본 생성자를 제공해야 함
∘ 기본 생성자는 JPA 프로바이더가 객체를 생성할 때만 사용
4.3.3 필드 접근 방식 사용
∘ set 메서드는 내부 데이터를 외부에서 변경할 수 있게 하므로 캡슐화를 깰 위험이 있음
∘ 객체가 제공할 기능 중심으로 엔티티를 구현하도록 만들려면 JPA 매핑 처리를 프로퍼티 방식이 아닌 필드 방식으로 선택∘ 해서 불필요한 get/set 메서드를 구현하지 말아야 함
4.3.4 AttributeComverter를 이용한 밸류 매핑 처리
∘ 두 개 이상의 프로퍼티를 가진 밸류 타입을 한 개 칼럼에 매핑 할 때 AttributeConverter 사용
∘ convertToDatabaseColumn() : 밸류 타입을 DB 칼럼 값으로 변환
∘ convertToEntityAttribute() : DB 칼럽 값을 밸류로 변환
∘ AttributeConverter 인터페이스를 구현한 클래스는 @Converter 애너테이션 표시
4.3.5 밸류 컬렉션:별도 테이블 매핑
∘ 밸류 컬렉션을 별도 테이블로 매핑할 때는 @ElementCollection, @CollectionTable을 사용
4.3.6 밸류 컬렉션:한 개 칼럼 매핑
∘ 밸류 컬렉션을 별도 테이블이 아닌 한 개 칼럼에 저장해야 할 때 AttributeConverter를 이용
∘ AttributeConverter를 사용하려면 밸류 컬렉션을 표현하는 새로운 밸류 타입을 추가해야 함
4.3.7 밸류를 이용한 ID 매핑
∘ 밸류 타입을 식별자로 매핑하면 @Id 대신 @EmbeddedId 애너테이션 사용
4.3.8 별도 테이블에 저장하는 밸류 매핑
∘ 애그리거트에서 루트 엔티티를 뺀 나머지 구성요소는 대부분 밸류
∘ 애그리거트에 속한 객체가 고유 식별자를 갖는지를 확인해서 밸류인지 엔티티인지 구분
∘ 매핑되는 테이블의 식별자를 애그리거트 구성요소의 식별자와 혼동하면 안 됨
4.3.9 밸류 컬렉션을 @Entity로 매핑하기
∘ 개념적으로 밸류이지만 @Entity로 매핑해야 될 때 있음
∘ JPA는 @Embeddable 타입의 클래스 상속 매핑을 지원하지 않으므로 상속 구조를 갖는 밸류 타입을 사용하려면 @Entity를 이용해서 상속 매핑으로 처리해야 함
4.3.10 ID 참조와 조인 테이블을 이용한 단방향 M-N 매핑
∘ 애그리거트 간 집합 연관을 사용해야 한다면 ID 참조를 이용한 단방향 집합 연관 적용할 수 있음
4.4 애그리거트 로딩 전략
∘ 애그리거트 루트를 로딩하면 루트에 속한 모든 객체가 완전한 상태여야 함
∘ 조회 시점에 애그리거트를 완전한 상태가 되도록 하려면 애그리거트 루트에서 연관 매핑의 조회 방식을 즉시 로딩으로 설정
∘ 컬렉션에 대한 로딩 전략을 FechType.EAGER로 설정하면 즉시 로딩 방식이 문제가 될 수 있음
∘ 일반적인 애플리ㅔ이션은 조회 기능 실행 빈도가 높으므로 상태 변경을 위한 지연 로딩으로 인한 실행 속도 저하는 큰 문제가 아님 -> 애그리거트 내의 모든 연관을 즉시 로딩으로 설정할 필요 없음
4.5 애그리거트의 영속성 전파
∘ 애그리거트는 저장하거나 삭제할 때도 하나로 처리되어야 함
4.6 식별자 생성 기능
∘ 식별자 생성 방식
- 사용자가 직접 생성 ex. 이메일
- 도메인 로직으로 생성
- DB를 이용한 일련번호 사용
∘ DB 자동 증가 칼럼을 식별자로 사용할 때 식별자 매핑에서 @GeneratedValue 사용
∘ JPA의 식별자 생성 기능을 사용하면 저장 시점에 식별자 생성됨
4.7 도메인 구현과 DIP
∘ 완전히 순순한 도메인 모델을 만드는 것보다 특정 기술에 적당히 의존하는 도메인 모델을 만드는 것이 바람직함
'Back-End > 도메인 주도 개발 시작하기' 카테고리의 다른 글
[DDD] 도메인 주도 개발 시작하기 Ch6 (0) | 2024.03.25 |
---|---|
[DDD] 도메인 주도 개발 시작하기 Ch5 (0) | 2024.03.25 |
[DDD] 도메인 주도 개발 시작하기 Ch3 (0) | 2024.03.18 |
[DDD] 도메인 주도 개발 시작하기 Ch2 (0) | 2024.03.10 |
[DDD] 도메인 주도 개발 시작하기 Ch1 (0) | 2024.03.10 |