다대다 관계같은 경우에는 관계형 DB에서는 물론이고 엔티티에도 거의 사용하지않음
여기서 *은 N, 즉, 다 를 의미
주소(Address): 값 타입(임베디드 타입)이다. 회원과 배송(Delivery)에서 사용한다.
OrderItem은 다대다관계를 풀어내는 용도
그래서 Order가 OrderItem을 리스트로 가지고있다.
Delivery에서의 주소는 배송지 정보 (Member의 주소와는 다를수도 있으므로)
Category-Item은 ManyToMany를 설정할 수 있게함 (예제이므로 설명하기위해)
주문, 멤버 사이 양방향으로 엔티티를 갖는데 이건 좋지않다.
- 단방향으로 설계해야함.
- 예제니깐 넘어가쟈
- 사실해결하려면 Order안에 멤버를 냄기고 멤버에서 orders지우기
- 접근할때 Order안에서 멤버를 타고 접근 (전부 탐색)하면될듯?
아이템은 그냥 한개에 몰아서 표현한것 뿐
카테고리도 다대다 풀어서 쓰기
연관관계 매핑 분석
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;
@OneToMany(mappedBy = "member") //양방향이므로 연관관계의 주인이 아님을 설정 (order테이블안에 있는 member속성으로 접근)
private List<Order> orders = new ArrayList<>();
}
package jpabook.jpashop.domain;
import lombok.Getter;
import javax.persistence.Embeddable;
@Embeddable
@Getter
public class Address {
private String city;
private String street;
private String zipcode;
protected Address() { // jpa 스펙 상 기본생성자가 있긴해야함 프로텍티드인 이유는 상속할일이 없지만 그냥 다들 암묵적으로 사용(안전)
}
public Address(String city, String street, String zipcode) { //세터대신 사용 (값을 변경하면 안되기때문에 초기값을 그대로들고가도록 설계)
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
}
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
@JoinColumn(name = "member_id") //매핑에 사용할 이름 지정
//양방향이므로 연관관계의 주인으로 설정 (아무설정 안한것이 주인)
private Member member;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL) //order이 저장 혹은 삭제될때 orderlist에 있는 아이템들도 같이 진행
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne
@JoinColumn(name = "delivery_id",cascade = CascadeType.ALL)
private Delivery delivery;
private LocalDateTime orderDate; // 시간 분까지 다있음 주문시간
@Enumerated(EnumType.STRING)
private OrderStatus status; // 주문상태 ORDER, CANCEL
}
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_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;// 주문당시 수량
}
package jpabook.jpashop.domain;
public enum OrderStatus {
ORDER,CANCEL
}
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
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)//상속 전략을 잡아줘야함 (Joined 는 가장 정교하게,SINGLE_TABLE은 한테이블에 다 떄려박음
@DiscriminatorColumn(name = "dtype") //구분할때 예를들어 book이면 어쩔거냐~? 그내용을 상속받는 각각의 클래스에 적는다 @DiscriminatorValue로 받고
@Getter @Setter
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<>();
}
package jpabook.jpashop.domain.item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@DiscriminatorValue("A")
@Getter
@Setter
public class Album extends Item{ //extend => 상속
@Id
@GeneratedValue
@Column(name= "member_id")
private String artist;
private String etc;
}
package jpabook.jpashop.domain.item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@DiscriminatorValue("B")
@Getter
@Setter
public class Book extends Item{
@Id
@GeneratedValue
@Column(name= "member_id")
private String author;
private String isbn;
}
package jpabook.jpashop.domain.item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@DiscriminatorValue("M")
@Getter
@Setter
public class Movie extends Item{
@Id
@GeneratedValue
@Column(name= "member_id")
private String directer;
private String actor;
}
package jpabook.jpashop.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@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)//절대 EnumType.ORDINARY로 쓰지않기//중간에 하나 다른값이 들어온다면 순서가 밀려서 망해버린다.
private DeliveryStatus status; //READY, COMP
}
package jpabook.jpashop.domain;
public enum DeliveryStatus {
READY,COMP
}
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 //다대다는 조인테이블이다
@JoinTable(name = "category_item", //결국 이건 오더 오더아이템 아이템처럼 중간을 풀어내서 다시쓰는느낌
joinColumns = @JoinColumn(name = "category_id"), // 중간테이블에 있는 카테고리
inverseJoinColumns = @JoinColumn(name = "item_id")) // 중간테이블에 있는 아이템
private List<Item> items = new ArrayList<>();
@ManyToOne//(fetch = FetchType.LAZY)//
@JoinColumn(name = "parent_id")
private Category parent;//카테고리는 쭈욱 타고 내려오므로~ 상위계층이 필요
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();//자식은 여러갤 가질수 있다. (하위계층 카테고리는 많을수있으므로)
}
두 엔티티를 생성하고 저장할때 서로 따로 생성했다면, 그 둘의 관계를 엮어줘야한다.
(Order클래스)만약 이 코드의 member.getOrders().add(this); 이 부분이없다면
public void setMember(Member member){
this.member = member;
member.getOrders().add(this);
}
여기서 이렇게 두개 다 연결해주어ㅑ한다. 하지만 위의 코드가 있다면 member.getOrders().add(order);이녀석은 생략해도된다.
public static void main(String[] args){
Member member = new Member();
Order order = new Order();
member.getOrders().add(order);
order.setMember(member);
}
나머지 연관관계도 다 설정 (양뱡향만~~~)