1. Entity Relationships
4가지 타입
@OneToOne
@OneToMany, @ManyToOne
@ManyToMany
relationship의 방향성이 있다.
- bidirectional (양방향) : owning side(referenece를 가지고 있는 side) and inverse side
- unidirectional (일방향) : owning side only
2. Entity Relation Attributes
Cascading updates/deletes
- CascadeType : ALL, PERSIST, MERGE, REMOVE, REFRESH
- default 값 : no operation
@OneToMany(cascade = CascadeType.ALL, fetch = FethType.LAZY)
Fetch
Fetch Type : LAZY, EAGER
예 ) 특정 고객을 조회하면, 고객이 주문한 Orders 도 메모리 상에 load를 할 것인가?
- load 한다 -> EAGER (함께 로드됨)
- load 하지 않는다 -> LAZY : 특정 order가 조회될 때 까지 load 되지 않는다. (실제로 조회될떄 까지 로드x)
=> 퍼포먼스 최적화를 위함.
Mapping | Default Fetch Type |
@OneToOne | FetchType.EAGER |
@OneToMany | FetchType.LAZY |
@ManyToOne | FetchType.EAGER |
@ManyToMany | FetchType.LAZY |
예시를 통해 알아보자.
1) OneToMany
1.1) Unidirectional
public class Category {
@Id
@GeneratedValue
private int id;
private String name;
}
public class Product {
@Id
@GeneratedValue
private int id;
private String name;
private int price;
private String description;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="category_id")
private Category category;
}
- foreign key를 many side에 둔다.
- Category (Parent) One side , Product(Child) Many Side <- 여기서 foreign key를 갖는다.
- 어떤 객체가 Parent 인지 Hibernate에게 알려주기 위해 @ManyToOne를 사용한다.
- 어떤 컬럼이 조인 컬럼인지 알기 위해 @JoinColumn을 사용한다. (이름 지정 가능)
- cascade는 parent에 옮기는 것이 좋다.
1.2) Bidirectional
public class Category {
@Id
@GeneratedValue
private int id;
private String name;
@OneToMany(mappedBy="category", cascade=CascadeType.ALL,
fetch = FetchType.LAZY)
private Set<Product> products;
}
public class Product {
@Id
@GeneratedValue
private int id;
…
@ManyToOne
@JoinColumn(name="category_id")
private Category category;
}
- 실제 DB에서는 JoinColumn으로 Unidirectional과 같이 사용하지만, Java 객체 모델에서 양방향으로 구현이됨.
- one to many는 여러개의 reference가 있다.
- @OneToMany(mappedBy="??") => ??는 many사이드에서 조인컬럼의 category와 같아야된다.
2) OneToOne
2.1) Unidirectional
public class Person {
@Id
@GeneratedValue
@Column(name="person_id")
private long id;
private String firstName;
private String lastName;
}
public class License {
@Id
@GeneratedValue
@Column(name="license_id")
private long id;
private String license_number;
private Date issue_date;
@OneToOne(optional=false, cascade=CascadeType.ALL)
@JoinColumn(unique=true, name="person_id")
private Person person;
// optional : 값이 꼭 존재 해야하는지?
// unique : 유일해야 하는지?
}
2.2) Bidirectional
public class Person {
@Id
@GeneratedValue
@Column(name="person_id")
private long id;
private String firstName;
private String lastName;
@OneToOne(mappedBy="person", cascade=CascadeType.ALL)
private License license;
}
public class License {
@Id
@GeneratedValue
@Column(name="license_id")
private long id;
private String license_number;
private Date issue_date;
@OneToOne(optional=false)
@JoinColumn(unique=true, name="person_id")
private Person person;
}
3) ManyToMany
3.1) Unidirectional
public class Author {
@Id
@GeneratedValue
@Column(name="author_id")
private long id;
@Column(name="author_name")
private String name;
}
public class Book {
@Id
@GeneratedValue
@Column(name = "book_id")
private long id;
@Column(name = "book_name")
private String title;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "author_book",
joinColumns = { @JoinColumn(name = "book_id") },
inverseJoinColumns = { @JoinColumn(name = "author_id") })
private Set<Author> authors ;
}
- Join Table : 각 테이블의 PK를 가지고 있음. 테이블 명은 Table1_Table2 로 지어준다.
'Backend > Spring & SpringBoot' 카테고리의 다른 글
[Spring Boot] Spring Data JPA의 사용법과 사용이유, 예시 (0) | 2022.03.07 |
---|---|
[Spring Boot] Spring에서의 Hibernate 사용법 (0) | 2022.03.07 |
[Spring boot] JPA vs Hibernate (0) | 2022.03.07 |
[Spring Boot] Hibernate 의 동작 원리 및 특징과 사용 예시 (1) | 2022.03.05 |
[Spring Framework] 03_03. 요청 파라미터 처리 방법 (0) | 2020.08.18 |