Spring/SpringBoot

#3 엔티티 생성 + JPA관계형DB 설계

SK_MOUSE 2022. 4. 3. 17:55
반응형

엔티티 생성

Enum :

- DeliveryStatus

- OrderStatus

Class :

- Member

- Order

- OrderItem

- Delivery

- Address

- Item ==(상속)==> Album,Book,Movie

- Category


세부 내용

@Id

  • 직접할당.
  • 엔티티의 기본키 필드에 값을 직접 넣어 등록한다.

@GeneratedValue

  • 자동할당
속성값 설명 대표DBMS
strategy = GenerationType.IDENTITY 기본키 생성을 데이터베이스에 위임.  MYSQL
strategy = GenerationType.SEQUENCE 시퀀스 사용, @SequenceGenerator 필요(시퀀스 생성) ORACLE
strategy = GenerationType.TABLE 키 생성용 테이블 사용, @TableGenerator 필요 모든 DBMS
strategy = GenerationType.AUTO 데이터베이스 방언에 따라 자동 지정(기본값)  

 

@OneToMany, @ManyToOne, @OneToOne, @ManyToMany ...

  • 일대다, 다대일, 다대다 관계를 모두 넣어서 설계.
  • 다대다 관계는 실무에서는 '다대일 + 일대다' 관계로 풀어서 설계하도록 해야함.
  • 관계 정의 후 관계의 주인 설정(mappedBy 이용)
* 1대 다의 경우 List나 Set으로 받아올것!
즉 mappedBy = "student"는 양방향 연관관계일때 반대쪽에 매핑되는 엔티티의 필드값을 준다.
연관관계의 주인은 mappedBy 옵션을 사용하지 않는다.
이때 양방향 연관관계일 경우, 연관관계의 주인은 외래키를 가지고 있는 쪽으로 생각하면 된다.

 

//예시 : 양방향 + 일대일
@Entity
public class Delivery {

    @Id @GeneratedValue
    @Column(name="delivery_id")
    private Long id;
    
	//★★여기 mapped by사용★★
    @OneToOne(mappedBy = "delivery", fetch = FetchType.LAZY)
    private Order order;

    //생략
}

@Entity
@Table(name = "orders")
public class Order {
    @Id
    @GeneratedValue
    @Column(name = "order_id")
    private Long id;
    
    //...중략...
    
    //★★여기 mapped by사용★★
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "delivery_id")
    private Delivery delivery;
 }

 

@JoinColumn(name = "외래키 명")

조인컬럼은 외래키를 매핑할 때 사용한다.

name 속성에는 매핑할 외래키 이름을 지정한다.

OrderItem의 경우 Item, Order의 외래키 필요

 

@Entity
@Table(name = "order_item")
@Getter @Setter
public class OrderItem {

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

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "item_id") //★★여기 JoinColumn 외래키 적용★★
    private Item item;
    
    //★★여기 JoinColumn 외래키 적용★★
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "order_id")//양방향일때 해줘야됨
    private Order order;


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

}

 

상속관계 JPA 매핑방법 3가지

1. 조인 전략(정석적이지만 조인 성능bad)

 

2. 단일 테이블 전략(성능 good)

 

3. 구현 클래스마다 전략 (이건 사용 x)

JPA가 이 세가지 방식과 매핑하려면

  • @Inheritance(strategy=InheritanceType.XXX)의 stategy를 설정해주면 된다.
    • default 전략은 SINGLE_TABLE(단일 테이블 전략)이다.
    • InheritanceType 종류
      • JOINED
      • SINGLE_TABLE
      • TABLE_PER_CLASS
  • @DiscriminatorColumn(name="DTYPE")
    • 부모 클래스에 선언한다. 하위 클래스를 구분하는 용도의 컬럼이다. 관례는 default = DTYPE
  • @DiscriminatorValue("XXX")
    • 하위 클래스에 선언한다. 엔티티를 저장할 때 슈퍼타입의 구분 컬럼에 저장할 값을 지정한다.
    • 어노테이션을 선언하지 않을 경우 기본값으로 클래스 이름이 들어간다.
@Entity
@DiscriminatorValue("B")
@Getter @Setter
public class Book extends Item {//자식 클래스
    private String author;
    private String isbn;
}

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) //상속 타입(한테이블에 다때려박는것)
@DiscriminatorColumn(name = "dtype")//구분할때 타입. book/album/movie
@Getter @Setter
public abstract class Item{//부모 클래스

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

    //상속속성들.(Album,Book,Movie)
    private String name;
    private int price;
    private int stockQuantity;

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



출처: https://ict-nroo.tistory.com/128 [개발자의 기록습관]

 

[JPA] 상속관계 매핑 전략(@Inheritance, @DiscriminatorColumn)

상속관계 매핑 객체는 상속관계가 존재하지만, 관계형 데이터베이스는 상속 관계가 없다.(대부분) 그나마 슈퍼타입 서브타입 관계라는 모델링 기법이 객체 상속과 유사하다. 상속관계 매핑이라

ict-nroo.tistory.com

 

반응형