WEB JAVA SPRING/PROJECT

[Day-4] 도메인 모델과 테이블 설계, 엔티티 클래스 개발 1

sshhhh 2023. 8. 25.

[도메인 분석 설계]

<도메인 모델과 테이블 설계>

 

#참고

 *(다) 

- 무조건 여기에 외래키 존재 , 외래키를 연관관계 주인으로 잡아야함

  ex) 자동차 - 바퀴(외래키) 그래야 유지보수 쉽다.

- 주인쪽에 값을 세팅해야 값 바뀜

- 1쪽은 그냥 읽는데만 쓰임

 

엔티티(Entity)

- 객체 , 추상적

- DB에서 한 건의 자료를 구성하는 레코드로 속성을 가진다. ex) 과목 : 국,영,수

- DB나 SQL상에 존재하지 않는다. 테이블과 달리 그냥 일종의 개념이다.

- 엔티티 사이의 관계: 릴레이션(relationship)

- 이것을 도표로 나타낸 것 : ERD(Entity Relationship Diagram)

- 도메인 > 엔티티 > 속성

 

 

테이블

- 테이블은 데이터베이스나 SQL에 실제로 존재하며 물리적인 구조를 지니고 있다.

 

 

엔티티, 테이블의 차이

엔티티 테이블
속성, 어트리뷰트(Attribute) 컬럼(Column)
관계, 릴레이션(Relation) 관계, 릴레이션(Relation)
키 그룹(Key group) 인덱스(Index)
엔티티(Entity) 테이블(Table)

 

https://velog.io/@keywookim/We.TIL-35-%EC%97%94%ED%8B%B0%ED%8B%B0%EC%99%80-%ED%85%8C%EC%9D%B4%EB%B8%94%EC%9D%98-%EC%B0%A8%EC%9D%B4

 

We.TIL 36 : 엔티티와 테이블의 차이

엔티티는 데이터베이스나 SQL상에 존재하지 않는다. 테이블과 달리 엔티티는 실제로 존재하지 않는 아닌 일종의 개념이다.그러나 테이블은 데이터베이스나 SQL에 실제로 존재하며 물리적인 구조

velog.io

 

 


 

#도메인 모델과 테이블 설계

 

회원, 주문, 상품의 관계

-회원 : 상품 여러개 주문 가능

-한 번 주문할 때 여러 상품 선택 가능 = > 주문과 상품은 다대다 관계

-하지만 이런 다대다 관계는 관계형 데이터베이스+ 엔티티에서 거의 사용하지 않는다.

-주문상품이라는 엔티티 추가 -> 다대다 관계를 일대다, 다대일 관계로

 

상품 분류

-도서, 음반, 영화로 구분

-상품이라는 공통 속성을 사용-> 상속 구조

 

 

#회원 엔티티 분석

 

 

 

 

 

회원(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;
}

 

 

 

강의 : https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/dashboard

 

 

 

 

 

'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

댓글