본문 바로가기

개발/JPA

[강의 요약 노트]실전! 스프링 부트와 JPA 활용1 : (2)도메인 분석 설계

도메인 모델과 테이블 설계

주문-상품은 다:다 관계이므로, 주문과 상품 사이에 주문 상품을 끼운다.

 

테이블별 중요사항

Member

1) Address: 내장타입(Embeded Type)  

- 연관된 데이터는 하나의 객체로 묶어, 내장 타입으로 사용하는 것이 낫다. (예. 국가, 도시, 우편번호 -> 주소로 묶자)

- 값타입은 Setter 절대 사용 금지. 

예시. https://devlog-wjdrbs96.tistory.com/405 ( 상세 설명은 기본편 참고)

 

[JPA] 9장: 값 타입이란 무엇일까?

값 타입 분류 JPA의 데이터 타입을 크게 분류하면 엔티티 타입 과 값 타입 으로 나눌 수 있습니다. 엔티티 타입은 @Entity로 정의하는 객체이고, 값 타입은 int, Integer, String 처럼 단순히 값으로 사용

devlog-wjdrbs96.tistory.com

 

회원엔티티 분석에서 주목

1) 1:다 관계 / 1:1 관계 / 상속 (Item - Album) / Many to many

2) -> JPA 실무에서 many to many는 쓰면 안된다. (기본편에 이유 나옴)

3) Member와 Order는 양방향 관계다. -> 되도록 단방향 관계로 바꾸자. (예제는 공부용으로 넣어둔것)

 

테이블

ITEM-> 싱글테이블 전략사용. (DTYPE으로 종류 구분) 

         -> 특정 카테고리에만 필요한 컬럼이 다 들어가긴 하지만, (ACTOR, ISBN..) 성능은 낫다. 

 

관계형 데이터베이스는 다:다 관계가 안된다. 

따라서 중간에 매핑 테이블을 둬야한다.  (CATEGORY_ITEM을 두고 1:다, 다:1로 풀어냄 -> 데이터베이스 기본이라고 함. 구글링 필요)

 

연관관계 매핑

1:다 관계

예) 회원(MEMBER)-주문(ORDERS): 외래키가 있는 주문을 연관관계의 주인으로 정하자. 

-> 매핑 관계 수정 필요시  ORDERS의 값이 변경되어야함. 

 

1:1 관계

예) 주문(ORDERS)-배송(DELIVERY): 외래키를 둘 중 아무 곳이나 둬도 무방. 

 

** 중요  **

외래키가 있는 곳을 연관관계의 주인으로 정해라. 

예) 자동차, 바퀴 -> 바퀴가 주인이다.

 

엔티티 클래스 개발1

주의: 공부할 때는 Getter, Setter 다 열어뒀지만, 실무에서는 변경을 위해 별도의 비즈니스 메서드를 사용해야하며, Setter는 다 닫아야한다. 

 

OneToMany vs ManyToOne 비교

Order의 입장에서 member는 하나. 
member의 입장에서 Order는 여러개. 

 

ITEM과 ALBUM/BOOK/MOVIE 연결법

1) 부모 클래스(Item)에서 전략을 지정. 

2) 자식 클래스는 구분자 값을 DiscriminatorValue에서 지정

cf)

SINGLE_TABLE: 한 테이블에 자식 클래스 속성 모두 넣음

JOINED: 정규화, 

TABLE_PER_CLASS: Item 없이 Book, album, movie로 나눈것

 

Enumerated

EnumType을 쓸 경우 Ordinary 대신 STRING 구분자를 사용하자. 

이유: 타입이 READY 와 COMP인데, 그 사이에 다른 타입이 추가될 경우, 2를 새로운 타입이 사용하므로, 장애남. 

Order - Delivery (1:1 관계)

엑세스를 많이 하는 곳에 FK를 두는 것이 보편적. (주문을 가지고 배송을 조회하므로, 주문에 FK를 두자)

**Delivery에 둬도 무관하긴 함. 

엔티티 클래스 개발2

Item-Category(다:다 관계)

-> 중간 테이블을 둔다. 

-> 실무에서는 ManyToMany 사용 금지. (FK 외에도 다른 컬럼이 필요할 경우를 만들 수 없다)

엔티티 설계시 주의점

1. 엔티티에서는 가급적 Setter를 사용하지 말자. (엔티티의 변경 시점을 명확히 알기 어려울 수 있다. 비즈니스 메서드로 대체하라)

 

2. 모든 연관관계는 지연로딩으로 설정하자. 

- 성능이슈: 예를 들어, Member가 Team을 지닐 경우, Team은 나중에 로딩되는 것이 성능 측면에서 유리. 하지만 두 정보 모두 자주 함께 조회된다면, 즉시로딩(Eager)을 사용하는 것이 낫다.  ( 그 전까지는 Proxy 객체가 제공된다)

 

3. 컬렉션은 필드에서 바로 초기화하자.(?)

 

4. 테이블, 컬럼명 생성 전략

소문자 + 언더스코어 조합(_)