jae_coding

[Spring Project] 엔티티 클래스 개발 본문

Spring, java/Spring_Project

[Spring Project] 엔티티 클래스 개발

재코딩 2022. 8. 21. 21:04
반응형

 

 

목차

  • 설계
  • 회원 엔티티
  • 주문 엔티티
  • 주문상태
  • 상품주문 엔티티
  • 상품 엔티티
  • 상품 하위 엔티티 (BOOK, ALBUM, MOVIE)
  • 배송 엔티티
  • 배송상태
  • 카테고리 엔티티
  • 주소
  • 테이블 생성화면
  • 실무 개발 팁

0. 설계

Domain model & table

 

 

Analysis member entity

 

 

Analysis member table

1. 회원 엔티티

package jpabook.jpashop.domain;


import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@Setter
public class Member {

    @Id
    @GeneratedValue
    @Column(name = "member_id")
    private Long id;

    private String name;

    @Embedded
    private Address address;

    //mapping이 된 거울이된 느낌(읽기 전용)
    @OneToMany(mappedBy = "member")
    private List<Order> orders = new ArrayList<>();
}

2. 주문 엔티티

package jpabook.jpashop.domain;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "orders")
@Getter
@Setter
public class Order {
    @Id @GeneratedValue
    @Column(name = "order_id")
    private Long id;

    //다대일 관계
    @ManyToOne
    //FK (연관관계의 주인)
    @JoinColumn(name = "member_id")
    private Member member;

    @OneToMany(mappedBy = "order")
    private List<OrderItem> orderItems = new ArrayList<>();

    @OneToOne
    //FK (연관관계의 주인)
    @JoinColumn(name = "delevery_id")
    private Delivery delivery;

    // hibernate 지원해줌 (주문시간)
    private LocalDateTime orderDate;

    @Enumerated(EnumType.STRING)
    private OrderStatus status; // 주문상태 (ORDER, CANCEL)

}

3. 주문 상태

package jpabook.jpashop.domain;

public enum OrderStatus {
    ORDER, CANCEL
}

4. 상품주문 엔티티

 

package jpabook.jpashop.domain;

import jpabook.jpashop.domain.Item.Item;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;

@Entity
@Getter
@Setter
public class OrderItem {
    @Id @GeneratedValue
    @Column(name = "order_item_id")
    private Long id;

    @ManyToOne
    @JoinColumn(name="item_id")
    private Item item;

    @ManyToOne
    @JoinColumn(name = "order_id")
    private Order order;

    private int orderPrice; //주문 가격
    private int count; // 주문 수량

}

5. 상품 엔티티

 

package jpabook.jpashop.domain.Item;

import jpabook.jpashop.domain.Category;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@Setter
//상속관계 전략
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@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;

    @ManyToMany(mappedBy = "items")
    private List<Category> categories = new ArrayList<>();
}

6. 상품 하위 엔티티(BOOK, ALBUM, MOVIE)

BOOK

 

package jpabook.jpashop.domain.Item;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@Getter
@Setter
//상속관계 Mapping
@DiscriminatorValue("B")
public class Book extends Item {
    private String author;
    private String isbn;
}

ALBUM

 

package jpabook.jpashop.domain.Item;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@Getter
@Setter
//상속관계 Mapping
@DiscriminatorValue("A")
public class Album extends Item{
    private String artist;
    private String etc;
}

MOVIE

 

package jpabook.jpashop.domain.Item;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@Getter
@Setter
//상속관계 Mapping
@DiscriminatorValue("M")
public class Movie extends Item{
    private String director;
    private String actor;
}

7. 배송 엔티티

 

package jpabook.jpashop.domain;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;

@Entity
@Getter
@Setter
public class Delivery {
    @Id @GeneratedValue
    @Column(name = "delevery_id")
    private Long id;

    @OneToOne(mappedBy = "delivery")
    private Order order;

    @Embedded
    private Address address;

    @Enumerated(EnumType.STRING)
    private DeliveryStatus status; //(READY, COMP)

}

8. 배송 상태

 

package jpabook.jpashop.domain;

public enum DeliveryStatus {
    READY, COMP
}

9. 카테고리 엔티티

package jpabook.jpashop.domain;

import jpabook.jpashop.domain.Item.Item;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@Setter
public class Category {
    @Id @GeneratedValue
    @Column(name = "category_id")
    private Long id;

    private String name;

    @ManyToMany
    // 관계형 DB는 Collection관계를 양쪽에 가질 수 없기 때문에
    // 관계를 풀어낼 수 있도록 중간 테이블을 설정을 해주어야한다.
    // 실전에서 다대다는 사용할 수 없을 확률이 크다.
    @JoinTable(name = "category_item",
            joinColumns = @JoinColumn(name = "categoiy_id"),
            inverseJoinColumns = @JoinColumn(name = "item_id"))
    private List<Item> items = new ArrayList<>();


    //같은 Entity에 대해서 부모-자식 관계 설정하기
    @ManyToOne
    @JoinColumn(name = "parent_id")
    private Category parent;

    @OneToMany(mappedBy = "parent")
    private List<Category> child = new ArrayList<>();
}

10. 주소

package jpabook.jpashop.domain;

import lombok.Getter;

import javax.persistence.Embeddable;

@Embeddable
//값이라는 것은 변경이 되어야하지 않게 세팅을 하기위해서 Setter을 제공하지 않는다. (변경 불가)
@Getter
public class Address {

    private String city;
    private String street;
    private String zipcode;

    protected Address(){
    }

    public Address(String city, String street, String zipcode){
        this.city = city;
        this.street = street;
        this.zipcode = zipcode;
    }
}

 

11. 테이블 생성화면

H2 Database

 

 

 

 

Hibernate를 통한 SQL 생성 로그

 

 

 

12. 실무 개발 팁

  • 실무에서는 Setter를 너무 많이 사용하게되면, 변경 포인트가 너무 많기 때문에 유지 보수가 어렵다. 엔티티 수정이 어떻게 되는지 파악하기가 어렵다. (나중에 변경해어야될때, 모든 엔티티를 보면서 유지보수를 해야하기 때문에 Setter을 줄어야한다)-> Getter는 열고 Setter는 닫아야한다.
  • Table의 소속을 알기위해서 class의 소문자or대문자_ id로 만드는 것이 관례상 스타일을 추구하는 것이 편하다.
  • 실무에서는 @ManyToMany를 사용하지마라! (중간테이블이 만들어지기때문에 다른 데이터를 넣지못한다.) <실무에서는 등록일, 수정일이 들어가야한다>
  • addressd와 같은 값 타입은 변경 불가능하도록 설계하여야한다. (Setter 제거, public으로 설정하기보다는 protected사용)

 

자료 출처: 인프런 김영한 JPA 활용 1

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형
Comments