[도메인 분석 설계]
<도메인 모델과 테이블 설계>
#참고
*(다)
- 무조건 여기에 외래키 존재 , 외래키를 연관관계 주인으로 잡아야함
ex) 자동차 - 바퀴(외래키) 그래야 유지보수 쉽다.
- 주인쪽에 값을 세팅해야 값 바뀜
- 1쪽은 그냥 읽는데만 쓰임
엔티티(Entity)
- 객체 , 추상적
- DB에서 한 건의 자료를 구성하는 레코드로 속성을 가진다. ex) 과목 : 국,영,수
- DB나 SQL상에 존재하지 않는다. 테이블과 달리 그냥 일종의 개념이다.
- 엔티티 사이의 관계: 릴레이션(relationship)
- 이것을 도표로 나타낸 것 : ERD(Entity Relationship Diagram)
- 도메인 > 엔티티 > 속성
테이블
- 테이블은 데이터베이스나 SQL에 실제로 존재하며 물리적인 구조를 지니고 있다.
엔티티, 테이블의 차이
엔티티 | 테이블 |
속성, 어트리뷰트(Attribute) | 컬럼(Column) |
관계, 릴레이션(Relation) | 관계, 릴레이션(Relation) |
키 그룹(Key group) | 인덱스(Index) |
엔티티(Entity) | 테이블(Table) |
#도메인 모델과 테이블 설계
회원, 주문, 상품의 관계
-회원 : 상품 여러개 주문 가능
-한 번 주문할 때 여러 상품 선택 가능 = > 주문과 상품은 다대다 관계
-하지만 이런 다대다 관계는 관계형 데이터베이스+ 엔티티에서 거의 사용하지 않는다.
-주문상품이라는 엔티티 추가 -> 다대다 관계를 일대다, 다대일 관계로
상품 분류
-도서, 음반, 영화로 구분
-상품이라는 공통 속성을 사용-> 상속 구조
#회원 엔티티 분석
회원(Member)
임베디드 타입인 주소( Address )
주문(Order)
-한 번 주문시 여러 상품을 주문할 수 있다 -> 주문과 주문상품( OrderItem )은 일대다 관계
-상품을 주문한 회원, 배송 정보, 주문 날짜, 주문 상태( status )
-주문 상태 : 열거형 주문( ORDER ), 취소( CANCEL ) 표현
주문상품(OrderItem)
-주문한 상품 정보,주문 금액( orderPrice ), 주문 수량( count ) 정보
(보통 OrderLine , LineItem 으로 많이 표현한다.)
상품(Item)
-이름, 가격, 재고수량( stockQuantity )
-상품을 주문하면 재고수량이 줄어든다.
-상품의 종류 : 도서, 음반, 영화
-orderItem으로 가지 못함.. 굳이 갈 이유가 없음..
배송(Delivery)
-주문시 하나의 배송 정보를 생성
-주문과 배송은 일대일 관계
-order와 양방향 관계
카테고리(Category)
-상품과 다대다 관계
-parent , child 로 부모, 자식 카테고리를 연결한다.
주소(Address)
-값 타입(임베디드 타입)
-회원과 배송(Delivery)에서 사용한다.
#회원 테이블 분석
MEMBER
회원 엔티티의 Address 임베디드 타입 정보가 회원 테이블에 그대로 들어갔다. 이것은 DELIVERY 테이블도 마찬가지다.
ITEM
앨범, 도서, 영화 타입을 통합해서 하나의 테이블로 만들었다. DTYPE 컬럼으로 타입을 구분한다.
#연관관계 매핑 분석
회원과 주문
-일대다 , 다대일, 양방향 관계
-fk: 주문 -> 연관관계 주인
-Order.member를 ORDERS.MEMBER_ID 외래키와 매핑한다. (앞: 엔티티, 뒤 : 테이블)
주문상품과 주문
-다대일, 양방향
-fk: 주문상품 -> 주문상품이 연관관계 주인
-그러므로 OrderItem.order를 ORDER_ITEM.ORDER_ID 외래 키와 매핑
주문상품과 상품
-다대일 단방향 관계
-OrderItem.item을 ORDER_ITEM.ITEM_ID 외래키와 매핑
주문과 배송
-일대일 양방향 관계
-Order.delivery를 ORDERS.DELIVERY_ID 외래키와 매핑
카테고리와 상품
@ManyToMany 를 사용해서 매핑한다.
<엔티티 클래스 개발1>
#파일구조
#엔티티
<참고>
@Column(name = "~") " : 회원테이블 pk컬럼명
private ~ : 회원엔티티 속성들
Member (->Address)
Member
@Entity //회원 엔티티
@Getter @Setter
public class Member { //엔티티타입
@Id @GeneratedValue
@Column(name="member_id") //pk 컬럼명 //엔티티의 식별자
private Long id;
private String name;
@Embedded
private Address address;
@OneToMany(mappedBy = "member") //하나의 회원, 여러개 상품 주문 : 일대다
//mappedBy : 연관관계 주인이 아니다. order 테이블에 있는 member필드에 의해 매핑된것
//읽기전용 : 여기에 값을 넣는다해서 외래키 값이 변경되지 않음
private List<Order> orders = new ArrayList<>();
}
Address
//주소
//@Embeddable //JPA의 내장 타입 Member에 썼으니 안써도..
@Getter
public class Address {
private String city;
private String street;
private String zipcode;
}
Order (->OrderStatus)
Order
@Entity
@Table(name = "orders") //order가 sql 예약어라 s붙임
@Getter
@Setter
public class Order { //주문엔티티
@Id
@GeneratedValue
@Column(name = "order_id") //테이블 컬럼 이름
private Long id;
//테이블 컬림들
@ManyToOne //order랑 member는 다대일 (서로반대) , 여러개 주문<-하나의 회원
@JoinColumn //매핑을 어떻게 할건지 : 연관관계 주인으로 fk
private Member member; //주문회원
@OneToMany(mappedBy = "order") //order에 의해서 매핑됐다 , 주인아님
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne //하나의 배송정보는 하나의 주문정보만 가져야 하니까
@JoinColumn(name = "delivery_id") //연관관계 주인 fk
private Delivery delivery; //배송정보
private LocalDateTime orderDate; //주문시간 @Date 안써도 자바8이상에선 지원
@Enumerated(EnumType.STRING)
private OrderStatus status; //주문상태 [ORDER ,CANCEL}
}
/*
* 회원엔티티
* Member는 orders를 list로 가지고 있다
* Order도 멤버를 가지고 있다 .양방향 참조중!
* 근데 문제는
* DB의 fk는 member_id 뿐
* member_id의 관계를 바꾸고 싶으면 외래키 값을 변경해야하는데
* Member에도 orders와 관련된 필드가 있고
* Order에도 멤버필드가 있는데
* 둘중에 jpa는 뭘 확인해서 fk를 바꿔야하냐?
* fk값 있는 쪽을 연관관계 주인으로해서 업데이트
* 그러면 fk없는 쪽은 읽기전용으로 된다.
*
*/
/*
일대일 관계일시에는 많이 참조하는 테이블에 외래키 둘것 그래서 주문정보에 둘거임 배송정보 말고
*/
OrderStatus
//enum : 열거형 타입 : 관련있는 문자열이나 숫자등 기본 자료형의 값을 고정 (final같은..)
public enum OrderStatus {
ORDER,CANCEL
}
OrderItem
//주문상태 엔티티
@Entity
@Getter
@Setter
public class OrderItem {
@Id
@GeneratedValue
@Column(name = "order_item_id")
private Long id;
@ManyToOne //orderItem 입장에서 item
@JoinColumn(name ="item_id" ) //fk
private Item item; //주문상품
@ManyToOne
@JoinColumn(name="order_id") //fk
//하나의 order(주문)이 여러개의 orderitem 가질 수 있다.
private Order order; //주문
private int orderPrice; //주문 가격
private int count; //주문 수량
}
Delivery (->Address , DeliveryStatus)
Delivery
@Entity
@Getter
@Setter
public class Delivery { //배송엔티티
@Id @GeneratedValue
@Column(name ="delivery_id")
private Long id;
@OneToOne(mappedBy = "delivery")
private Order order;
@Embedded
private Address address;
@Enumerated(EnumType.STRING)
//enum은 꼭 넣어야함
// ordinal : 숫자로 들어감..1,2,3 이렇게 들어가서 중간에 뭐가 끼면 숫자가 밀려 꼭 String으로 써야해
private DeliveryStatus status; //READY ,COMP
}
DeliveryStatus
public enum DeliveryStatus {
READY ,COMP
}
Item (->Album, Book, Movie)
Item
@Entity
@Getter @Setter
//구현체를 갖기 때문에 추상클래스
//회원 엔티티
@Inheritance(strategy = InheritanceType.JOINED) //joined : 가장 정규화된 스타일..싱글테이블
//상속관계다.. Item -> Album,Book, Movie
@DiscriminatorColumn(name = "dtype")
public abstract class Item {
@Id
@GeneratedValue
@Column(name = "item_id")
private Long id;
private String name;
private int price;
private int stockQuantity;
}
Album
@Entity
@Getter
@Setter
@DiscriminatorValue("A") //상속관계 매핑
public class Album extends Item{
private String artist;
private String etc;
}
Book
@Entity
@Getter @Setter
@DiscriminatorValue("B")
public class Book extends Item{
private String author;
private String isbn;
}
Movie
@Entity
@Getter
@Setter
@DiscriminatorValue("M")
public class Movie extends Item {
private String director;
private String actor;
}
'WEB JAVA SPRING > PROJECT' 카테고리의 다른 글
[Day-6] 엔티티 설계 (연관관계) (0) | 2023.08.25 |
---|---|
[Day-5] 엔티티 클래스 개발2 (0) | 2023.08.25 |
[Day-3] JPA와 DB설정, 동작확인 (0) | 2023.08.25 |
[Day-2] 라이브러리, H2 DB (0) | 2023.08.25 |
[Day-1] 초기 설정 (0) | 2023.08.25 |