[4] 스프링 부트와 JPA 활용 (2) - 도메인 & 테이블 설계 / Entity 설계 순서 & 주의점
도메인 분석 설계
[ 목차 ]
[ 요구사항 분석 ]
- 기능에 필요한각 엔티티를 간략화된 그림으로 나타냄
- 기능 목록
- 회원 기능
- 상품 기능
- 주문 기능
- 기타 요구사항
- 상품은 재고관리가 필요
- 상품의 종류는 도서 / 음반 / 영화
- 상품을 카테고리로 구분할 수 있음
- 상품 주문시 배송 정보를 입력할 수 있음
[ 도메인 모델 설계 ]
Address
는 임베디드 값 타입
OrderStatus
는 Enum 타입
으로 (ORDER
/ CANCEL
) 을 가짐
DeliveryStatus
는 Enum 타입
으로 (READY
/ COMP
) 를 가짐
Item
은 (Album
/ Book
/ Movie
)라는 자식 객체를 가진다 --> 상속관계
Category
에 있는 parent
와 child
는 셀프 참조
를 한다
[ 테이블 설계 ]
Item
과 그 하위 Album
/ Book
/ Movie
은 SINGLE_TALBE
전략으로 테이블 구성
Category
와 Item
은 N:M관계
로 테이블로 분리
됨
Entity
와 구분을 위해 대문자
로 작성했지만, 실제 개발
에는 소문자+언더스코어(_) 스타일을
적용
Entity 설계
[ Entity 설계 순서 ]
Entity 생성
& Entity간 연관관계
설정
: 양방향 연관관계
설정시 연관관계 주인
설정
fetch strategy
를 LAZY
로 설정
: @ManyToOne
/ @OneToOne
은 기본이 EAGER
이니까 수동으로 지정
해야함
영속성 전이
옵션 설정(CASCADE
)
: 영속성 전이
는 주로 양방향 연관관계
에서 주 테이블
에 해당하는 쪽에 작성함
- 연관관계 편의 메서드 작성
: 연관관계 주인
과 상관 없이 자주 사용되는 주 테이블
기준으로 작성
[ Entity 설계 주의점 ]
Entity
에는 가급적 Setter
를 사용하지 X
Setter
가 열려있으면 변경 포인트
가 많아져서 유지보수가 어려움
-
Setter
를 만들지 않거나 만들고 private
으로 사용
모든 연관관계
는 지연로딩(LAZY)
으로 설정
N+1문제
를 예방하기 위해 모든 연관관계
를 LAZY
로 설정
- 참조 객체 정보를
바로 조회
해야 한다면 fetch join
사용
컬렉션
은 필드
에서 초기화
하자
List<>
같은 컬렉션은 선언과 함께 초기화
를 해주자
- 그래야
null문제
에서 안전
Hibernate
가 제공하는 내장 컬렉션
으로 변경되어도 매커니즘
이 꼬이지 X
(만약 new
로 나중에 또 java컬렉션
으로 바뀌면 로직
에 문제
가 생길 수 있음)
@ManyToMany
는 절대 사용하지 X
- 절대 사용하지말고,
별도의 Entity
를 생성해서 1:N
/ M:1
연관관계를 설정
값 타입
은 항상 불변 객체
로 만들자
값이 공유되는 일
을 막기 위해 Setter
를 제거
해야 한다
값이 변경
된다면 new
키워드를 통해 새로 생성하면서 일부 값을 변경
해야 함
기본 생성자
를 반드시 꼭 만들어주자 (public
보다는 protected
로!)
--> JPA 구현 라이브러리
가 객체를 생성할 때 리플렉션
같은 기술을 사용
할 수 있도록 있어야 하기 때문