실전 예제 3 - 다양한 연관관계 매핑
"인프런 - 자바 ORM 표준 JPA 프로그래밍 강의를 듣고 작성한 글 입니다."
www.inflearn.com/course/ORM-JPA-Basic#
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런
JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다. 초급 웹 개발 프로그
www.inflearn.com
이번엔 다양한 연관관계 매핑 에서 배운 일대일, 다대다 와 같은 연관관계를 이용하여, 배송, 카테고리 도메인 클래스를 생성한 후 연관관계를 매핑해보자.
이번 글에서 매핑할 연관관계는 아래와 같다.
1. Order - Delivery : 일대일 양방향 매핑 - 외래 키는 주 테이블인 Order 테이블에 넣는다.
2. Category - Item : 다대다 양방향 매핑 - 연결 테이블로 매핑한다.(CATEGORY_ITEM)
1. Order - Delivery : 일대일 양방향 매핑
- Order.java
@OneToOne
@JoinColumn(name = "DELIVERY_ID")
private Delivery delivery;
Delivery 클래스의 경우 따로 enum 타입의 DeliveryStatus 클래스를 생성해 주어야 한다.
- Delivery.java
@Entity
public class Delivery {
@Id @GeneratedValue
private Long id;
// 배송지 주소
private String city;
private String street;
private String zipcode;
private DeliberyStatus status;
@OneToOne(mappedBy = "delivery")
private Order order;
}
- DeliveryStatus.java
public enum DeliberyStatus {
}
2. Category - Item : 다대다 양방향 매핑
Category 클래스의 경우,위의 Entity 매핑 테이블에 나와있듯이 클래스 내부에 자기자신과의 연관관계를 따로 만들어 주어야 한다.(parent : Category)
- Category.java
@Entity
public class Category {
@Id @GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "PARENT_ID")
private Category parent;
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();
// Category 클래스 내부에서 다대일 연관관계 매핑을 따로 만들어줬다.
@ManyToMany
@JoinTable(name = "CATEGORY_ITEM", joinColumns = @JoinColumn(name = "CATEGORY_ID")
, inverseJoinColumns = @JoinColumn(name = "ITEM_ID")) // 중간 테이블 매핑, 다대다 연관관계의 주인으로서 매핑된다.
private List<Item> items = new ArrayList<>();
}
위의 소스 코드를 보면 joinColumns, inverseJoinColumns 속성을 통해 CATEGORY_ITEM 연결 테이블에 매핑할 양측 도메인 클래스의(Category.java, Item.java) 외래 키를 지정해주고 있다.
- Item.java
@ManyToMany(mappedBy = "items") // 연관관계의 주인 클래스가 아니므로 mappedBy 속성을 활용한다.
private List<Category> categories = new ArrayList<>();
위와 같이 코드를 작성한 후 실행시키면 아래와 같은 hibernate SQL 을 출력하는 것을 볼 수 있다.
Hibernate:
create table Delivery (
id bigint not null,
city varchar(255),
status integer,
street varchar(255),
zipcode varchar(255),
primary key (id)
)
Hibernate:
create table Category (
id bigint not null,
name varchar(255),
PARENT_ID bigint,
primary key (id)
)
Hibernate:
create table CATEGORY_ITEM (
CATEGORY_ID bigint not null,
ITEM_ID bigint not null
) // 연결(중간) 테이블 생성
Hibernate:
create table ORDERS (
ORDER_ID bigint not null,
orderDate timestamp,
status varchar(255),
DELIVERY_ID bigint, // delivery 외래 키 값 생성
MEMBER_ID bigint,
primary key (ORDER_ID)
)
* 다대일 연관관계에 있어서 @ManyToOne, @OneToMany 어노테이션의 차이점?
- @OneToMany 어노테이션은 mappedBy 속성을 사용할 수 있는데 반해, @ManyToOne 어노테이션은 사용할 수 없다.
왜? : 다대일 연관관계를 사용할 경우 ManyToOne 어노테이션을 선언한 도메인 클래스가 반드시 연관관계의 주인이 되어야 하기 때문이다.