티스토리 뷰
0. 학생 테이블을 도입하여 과정과 학생의 Many to Many 관계를 설명한다.
0-1 상식적으로 과정이 삭제되었다고 학생 데이터가 삭제되면 안된다.
0-2 학생 정보가 삭제되었다고 과정 정보가 삭제되면 안된다.
0-3 즉 cascade에 delete가 포함되면 안된다.
0-4 이 예제는 Many to Many 관계이므로 기본 FetchType이 Lazy이다 별도 설정이 필요없다.
1. Many To Many Mapping에는 Join Table이라는 별도의 테이블을 작성해서 표현한다.
2 JoinTable 이란 두 테이블 사이에 매핑정보를 제공하기 위한 테이블이다.
2-1 이 테이블은 두 테이블을 연결하기 위해 두 테이블의 primary key를 매핑하고 있다.
2-2 이 예제에서는 course_student라는 이름의 Join Table을 사용한다.
3. 데이터 베이스 구조
3-1 지난 포스트에서 추가된 부분은
3-1-1 student 테이블과 과정과 학생 사이의 매핑정보를 제공하는 course_student이다.
3-2 아래의 도식이 변경된 데이터 베이스테이블이다.
4. Many to Many의 경우의 Annotation 설정이다.
4-1 이 경우는 테이블 양쪽이 같은 상태이기 때문에 방향성을 고려할 필요가 없다.
4-2 이 예제의 경우 학생과 과정은 둘 다 삭제 시 서로를 삭제하면 안된다.
4-2-1 한 명의 학생을 지웠다고 그 학생이 등록한 과정 자체를 삭제하면 안된다.
4-2-2 한 과정을 삭제했다고 삭제된 과정을 등록한 학생 정보 자체를 삭제하면 안된다.
4-2-3 cascade type에서 delete가 추가되어서는 안된다.
4-3 두 개의 테이블 관계가 서로를 포함하는 관계이므로 lombok의 @Data를 사용하면 안된다.
4-4 아래는 소스는 학생 Entity class이다. 특이한 부분은 @JoinTable이다.
4-4-1 Many to Many의 경우는 두 테이블이 특정한 column으로 연결된 것이 아닌 별도의 Table로 연결되어 있다.
4-4-2 @JoinTable 내에서 어떤 column이 어떤 테이블 정보를 참조하는지 설정하는 것이 필요하다.
4-4-3 이 예제에서는 Student Entity에서 정의하기 때문에 student_id가 JoinColumn이 된다.
4-4-3-1 joinColumns의 속성에 들어가는 @JoinColumn은 이전에 사용한 동일한 JoinColumn이다.
4-4-3-2 inverseColumns의 inverse의 의미는 반대편에서 참조하는 Entity를 말한다. 이 경우는 Course Entity이다.
@Entity
@Table(name = "student")
@Setter
@Getter
@NoArgsConstructor
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column
private String email;
@ManyToMany(cascade = {
CascadeType.DETACH,
CascadeType.MERGE,
CascadeType.PERSIST,
CascadeType.REFRESH
})
@JoinTable(name = "course_student",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private List<Course> courses;
public Student(String firstName, String lastName, String email) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public void addCourse(Course course) {
if (this.courses == null) {
this.courses = new ArrayList<>();
}
this.courses.add(course);
}
@Override
public String toString() {
return "Student [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]";
}
}
4-5 관계가 추가된 Course Entity Class이다.
4-5-1 Student entity 클래스와 거의 동일한 설정이 새로 추가된 List students 속성에 붙어 있다.
4-5-2 여기서는 Course 입장에서 기술하기 때문에 inverse는 Student Entity클래스가 된다.
@Entity
@Table(name = "course")
@Getter
@Setter
@NoArgsConstructor
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String title;
@ManyToOne(cascade = { CascadeType.DETACH,
CascadeType.MERGE, CascadeType.PERSIST,CascadeType.REFRESH })
@JoinColumn(name = "instructor_id")
private Instructor instructor;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "course_id")
private List<Review> reviews;
@ManyToMany(cascade = {
CascadeType.DETACH,
CascadeType.MERGE,
CascadeType.PERSIST,
CascadeType.REFRESH
})
@JoinTable(
name = "course_student",
joinColumns = @JoinColumn(name = "course_id"),
inverseJoinColumns = @JoinColumn(name = "student_id")
)
private List<Student> students;
public Course(String title) {
this.title = title;
}
@Override
public String toString() {
return "Course [id=" + id + ", title=" + title + "]";
}
public void addReview(Review review) {
if (this.reviews == null) {
this.reviews = new ArrayList<>();
}
this.reviews.add(review);
}
public void addStudent(Student student) {
if (this.students == null) {
this.students = new ArrayList<>();
}
this.students.add(student);
}
}
'Spring > Hibernate' 카테고리의 다른 글
Hibernate : Composition key 지정하기 (0) | 2020.05.20 |
---|---|
Hibernate : Many-To-Many Mapping - Part 2 (0) | 2020.05.08 |
Hibernate : One-To-Many Mapping Uni-Direction (0) | 2020.05.07 |
Hibernate : Lazy and Eager Loading (0) | 2020.05.07 |
Hibernate : One-To-Many Mapping Bi-Directional (0) | 2020.05.06 |
- Total
- Today
- Yesterday
- 도커 개발환경 참고
- AWS ARN 구조
- Immuability에 관한 설명
- 자바스크립트 멀티 비동기 함수 호출 참고
- WSDL 참고
- SOAP 컨슈머 참고
- MySql dump 사용법
- AWS Lambda with Addon
- NFC 드라이버 linux 설치
- electron IPC
- mifare classic 강의
- go module 관련 상세한 정보
- C 메모리 찍어보기
- C++ Addon 마이그레이션
- JAX WS Header 관련 stackoverflow
- SOAP Custom Header 설정 참고
- SOAP Custom Header
- SOAP BindingProvider
- dispatcher 사용하여 설정
- vagrant kvm으로 사용하기
- git fork, pull request to the …
- vagrant libvirt bridge network
- python, js의 async, await의 차이
- go JSON struct 생성
- Netflix Kinesis 활용 분석
- docker credential problem
- private subnet에서 outbound IP 확…
- 안드로이드 coroutine
- kotlin with, apply, also 등
- 안드로이드 초기로딩이 안되는 경우
- navigation 데이터 보내기
- 레이스 컨디션 navController
- raylib
- hibernate
- mapping
- 스프링부트
- 로그인
- one-to-one
- 매핑
- Many-To-Many
- WebMvc
- Security
- spring boot
- Angular
- 스프링
- jsp
- crud
- Spring Security
- RestTemplate
- form
- Validation
- 외부파일
- one-to-many
- login
- XML
- Spring
- 자바
- Rest
- 설정
- 하이버네이트
- MYSQL
- 상속
- 설정하기