Hibernate 中,@ManyToMany 关系用于表示两个实体类之间的多对多关系。Hibernate 通常通过一个**中间表(Join Table)**来实现这种关系。下面是详细说明和示例:

多对多关系的概念

数据库中,多对多关系意味着:

  • 一个 A 实体可以关联多个 B 实体;
  • 一个 B 实体也可以关联多个 A 实体;
  • 通常需要一张中间表来维护这种关系。

在 Hibernate 中如何实现

假设我们有两个实体:StudentCourse,一个学生可以选多门课程,一门课程也可以被多个学生选。

示例代码:

@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 的结构。