[자바 ORM 표준 JPA] JPA 실전 예제 3 - 다양한 연관관계 매핑
[자바 ORM 표준 JPA] JPA 실전 예제 3 - 다양한 연관관계 매핑
실전 예제 3 - 다양한 연관관계 매핑
요구사항 분석#
배송, 카테고리 추가 - 엔티티#
- 주문과 뱌송은 1:1(@OneToOne)
- 상품과 카테고리는 N:M(@ManyToMany)
배송, 카테고리 추가 - ERD#
Delivery.java 와 Category.java를 생성합니다.
일대일 양방향 관계 Order.java - Delivery.java#
- 주 객체은 외래키를 가지고 있는 Order.java
- @OneToOne
@JoinColumn(name = “DELIVERY_ID”)
private Delivery delivery;
- 대상 객체는 상대 객체인 Delivery.java
- @OneToOne(mappedBy = “delivery”)
private Order order;
Order.java - Delivery 객체 추가
외래키를 가지고 있는 주 객체
package jpabasic.jpashop.domain;
import javax.persistence.*;
import jpabasic.jpashop.domain.Member;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Entity
@Table(name = "ORDERS") // DB에 따라 ORDER가 예약어일 경우가 있어 ORDERS
public class Order {
public Order(){}
@Id
@GeneratedValue
@Column(name="ORDER_ID")
private Long id;
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus status;
@ManyToOne
private Member member;
@OneToMany(mappedBy = "order")
private List<OrderItem> orderItems = new ArrayList<>(); //관례상 초기 값을 두어 NullPointer Exception을 방지
@OneToOne
@JoinColumn(name = "DELIVERY_ID")
private Delivery delivery;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public LocalDateTime getOrderDate() {
return orderDate;
}
public void setOrderDate(LocalDateTime orderDate) {
this.orderDate = orderDate;
}
public OrderStatus getStatus() {
return status;
}
public void setStatus(OrderStatus status) {
this.status = status;
}
public Member getMember() {
return member;
}
public void setMember(Member member) {
this.member = member;
}
public List<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
public void addOrderItem(OrderItem orderItem) {
this.orderItems.add(orderItem);
orderItem.setOrder(this);
}
public void addMember(Member member) {
this.member = member;
member.getOrders().add(this);
}
}
Delivery.java -
대상 테이블 @OneToOne(mappedBy = “delivery”)
package jpabasic.jpashop.domain;
import javax.persistence.*;
@Entity
public class Delivery {
@Id @GeneratedValue
@Column(name = "DELIVERY_ID")
private Long id;
private String city;
private String street;
private String zipcode;
@Enumerated(EnumType.STRING)
private DeliveryStatus status;
@OneToOne(mappedBy = "delivery")
private Order order;
public void setId(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public DeliveryStatus getStatus() {
return status;
}
public void setStatus(DeliveryStatus status) {
this.status = status;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
}
console - ORDERS - Delivery
create table ORDERS (
ORDER_ID bigint not null,
orderDate timestamp,
status varchar(255),
DELIVERY_ID bigint,
member_MEMBER_ID bigint,
primary key (ORDER_ID)
)
create table Delivery (
DELIVERY_ID bigint not null,
city varchar(255),
status varchar(255),
street varchar(255),
zipcode varchar(255),
primary key (DELIVERY_ID)
)
alter table ORDERS
add constraint FKdbs21f1yi0coxy9y0kxw4g9jf
foreign key (DELIVERY_ID)
references Delivery
다대다 양방향 관계 Category.java - Item.java#
- 주 객체은 외래키를 가지고 있는 Category.java
- @ManyToMany
@JoinTable(
name = “CATEGORY_ITEM”,
joinColumns = @JoinColumn(name = “CATEGORY_ID”),
inverseJoinColumns = @JoinColumn(name =“ITEM_ID”)
)
private List- items = new ArrayList<>();
- 대상 객체는 상대 객체인 Item.java
- @ManyToMany(mappedBy = “items”)
private Listcategories = new ArrayList<>();
부모 자식 구조의 연관관계 Category.java - Item.java#
- 부모
- @ManyToOne
@JoinColumn(name = “parent_id”)
private Category parent; // 상위 카테고리
- 자식
- @OneToMany(mappedBy = “parent”)
private Listchild = new ArrayList<>(); // 자식 카테고리
Category.java
package jpabasic.jpashop.domain;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
public class Category {
@Id @GeneratedValue
@Column(name = "CATEGORY_ID")
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "parent_id")
private Category parent; // 상위 카테고리
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>(); // 자식 카테고리
@ManyToMany
@JoinTable(name = "CATEGORY_ITEM",
joinColumns = @JoinColumn(name = "CATEGORY_ID"),
inverseJoinColumns = @JoinColumn(name ="ITEM_ID")
)
private List<Item> items = new ArrayList<>();
public void setId(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
}
Item.java
package jpabasic.jpashop.domain;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
public class Item {
public Item(){
}
public Item(String name, int price, int stockQuantity) {
this.name = name;
this.price = price;
this.stockQuantity = stockQuantity;
}
@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<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getStockQuantity() {
return stockQuantity;
}
public void setStockQuantity(int stockQuantity) {
this.stockQuantity = stockQuantity;
}
}
console
create table Category (
CATEGORY_ID bigint not null,
name varchar(255),
parent_id bigint,
primary key (CATEGORY_ID)
)
create table CATEGORY_ITEM (
CATEGORY_ID bigint not null,
ITEM_ID bigint not null
)
create table Item (
ITEM_ID bigint not null,
name varchar(255),
price integer not null,
stockQuantity integer not null,
primary key (ITEM_ID)
)
alter table Category
add constraint FK5s5t2pfpxo0vnd1ihc43721ty
foreign key (parent_id)
references Category
alter table CATEGORY_ITEM
add constraint FKf1uerpnmn49vl1spbbplgxaun
foreign key (ITEM_ID)
references Item
alter table CATEGORY_ITEM
add constraint FKjip0or3vemixccl6vx0kluj03
foreign key (CATEGORY_ID)
references Category