Spring JPA[N:N]
다대다 [ N:N ]
다대다 매핑 방법은, RDB에서 정규화된 테이블 2개로 다대다 관계를 표현할 수 없습니다.
그래서 중간에 테이블을 하나 추가해서, 일대다, 다대일 관계로 풀어나가야 합니다.
다대다 [N:N->1:N,N:1] - 단방향
Student Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Entity
public class Student {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToMany
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private Set<Course> courses = new HashSet<>();
}
Cource Class
1
2
3
4
5
6
7
8
9
10
@Entity
public class Course {
@Id
@GeneratedValue
private Long id;
private String name;
}
다대다 [N:N->1:N,N:1] - 양방향
Student Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Entity
public class Student {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToMany
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private Set<Course> courses = new HashSet<>();
}
Cource Class
1
2
3
4
5
6
7
8
9
10
11
12
@Entity
public class Course {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToMany(mappedBy = "courses")
private Set<Student> students = new HashSet<>();
}
이처럼 ManyToMany를 어노테이션을 사용해서 다:다 연관관계 매핑을 하는 방법입니다.
JoinTalbe에 들어있는 여러가지 옵션을 사용해 편리하게 만들 수 있습니다.
하지만 편리하기 만들기 위해 이러한 방법을 사용한다면 실무에서 사용하기에는 분명한 한계가 존재합니다.
이러한 한계점을 돌파하기 위해서는 중간에 테이블을 하나 두고 연결하는 방법이 존재합니다.
다대다 [N:N->1:N,N:1] - 한계돌파
Student Class
1
2
3
4
5
6
7
8
9
10
11
12
@Entity
public class Student {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "student")
private Set<StudentCourse> studentCourses = new HashSet<>();
}
Course Class
1
2
3
4
5
6
7
8
9
10
11
12
@Entity
public class Course {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "course")
private Set<StudentCourse> studentCourses = new HashSet<>();
}
StudentCourse Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Entity
public class StudentCourse {
@Id
@GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "student_id")
private Student student;
@ManyToOne
@JoinColumn(name = "course_id")
private Course course;
}
StudentCourse라는 새로운 테이블을 만들고, 기존에 ManyToMany였던 테이블을 OneToMany -> ManyToOne -> OneToMany 라는 관계로 만들어 줍니다.
이렇게 하면 한계점이었던 단방향에서의 값 추가/삭제 어려움을 극복할 수 있고, 양방향에서는 양쪽 엔티티에서 서로를 참조할 수 있도록 하여 편리성을 높일수 있습니다.
결론
다대다를 연관관계를 맺고 싶을때는, @ManyToMany를 사용하는 것보다, 중간에 테이블을 하나 추가해줘서 OneToMany -> ManyToOne -> OneToMany로 풀어주면 @ManyToMany의 한계점을 돌파할 수 있습니다.
This post is licensed under CC BY 4.0 by the author.