在 Hibernate 中,@ManyToMany
关系用于表示两个实体类之间的多对多关系。Hibernate 通常通过一个**中间表(Join Table)**来实现这种关系。下面是详细说明和示例:
多对多关系的概念
在数据库中,多对多关系意味着:
- 一个 A 实体可以关联多个 B 实体;
- 一个 B 实体也可以关联多个 A 实体;
- 通常需要一张中间表来维护这种关系。
在 Hibernate 中如何实现
假设我们有两个实体:Student
和 Course
,一个学生可以选多门课程,一门课程也可以被多个学生选。
示例代码:
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
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<>();
}
@Entity
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToMany(mappedBy = "courses") // 由 Student 端维护关系
private Set<Student> students = new HashSet<>();
}
关键注解解释
@ManyToMany
:声明这是一个多对多的关系。@JoinTable
:指定中间表的表名和两个外键字段。joinColumns
:指定当前实体在中间表中的外键。inverseJoinColumns
:指定对方实体在中间表中的外键。mappedBy
:在不维护关系的一方使用,指明由哪边来维护(避免双向都建表)。
重要注意事项
- Hibernate 默认使用
Set
类型避免重复数据。 - 若只需要单向关联(例如只从 Student 访问 Course),另一边可以不写
mappedBy
。 - 如果你需要在中间表中加入额外字段(如选课时间),就要用一个实体来表示这个中间表,转为两个
@ManyToOne
的结构。