JPA之级联关系@OneToMany 和 @ManyToMany
程序员文章站
2022-04-12 20:28:31
...
JPA之级联关系@OneToMany 和 @ManyToMany
1. 双向@OneToMany
@Entity
@Table(name = "TEACHER")
public class Teacher {
@Id
@GenericGenerator(name = "jpa-uuid", strategy = "uuid")
@GeneratedValue(generator = "jpa-uuid")
@Column(name = "teacher_id")
private String teacherId;
// Teacher oneToMany Student
// 当删除Teacher,会级联删除该Teacher的所有Student
// 拥有mappedBy注解的实体类为关系被维护端
// mappedBy="teacher"中的teacher是Student中的author属性
@OneToMany(mappedBy = "teacher", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Student> students;
@Column(name = "teacher_name")
private String name;
@ManyToMany(mappedBy = "teachers")
private List<School> schools;
}
@Entity
@Table(name = "STUDENT")
public class Student {
@Id
@GenericGenerator(name = "jpa-uuid", strategy = "uuid")
@GeneratedValue(generator = "jpa-uuid")
@Column(name = "student_id")
private String studentId;
@Column(name = "student_name",length = 48)
private String name;
@Column(name = "student_age")
private int age;
@Column
private boolean gender;
// 要在关系的维护端,即 One 端。cascade只能写在 One 端。
// Student ManyToOne Teacher, Teacher就是one的一端
// optional=false,表示teacher不能为空。删除学生,不影响老师
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}, optional = false)
private Teacher teacher;
}
2. @ManyToMany和单向@OneToMany
@Entity
@Table(name = "SCHOOL")
public class School {
@Id
@GenericGenerator(name = "jpa-uuid", strategy = "uuid")
@GeneratedValue(generator = "jpa-uuid")
@Column(name = "class_id")
private String classId;
@Column(name = "class_name")
private String className;
// 在Student表增加一个外键列来实现一对多的 **单向关联**, Student表中会多一列classroom_id
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "classroom_id")
private List<Student> students;
/*多对多关系中一般不设置级联保存、级联删除、级联更新等操作。
可以随意指定一方为关系维护端,这里指定 SCHOOL 为关系维护端,所以生成的关联表名称为: school_teacher,关联表的字段为:classroom_id 和 teacher_id。
多对多关系的绑定由关系维护端来完成,即由 classroom.setTeacher(teacher) 来绑定多对多的关系。关系被维护端不能绑定关系,即Teacher不能绑定关系。
多对多关系的解除由关系维护端来完成,即由Classroom.getTeacher().remove(teacher)来解除多对多的关系。关系被维护端不能解除关系,即Teacher不能解除关系。
如果 SCHOOL 和 Teacher 已经绑定了多对多的关系,那么不能直接删除 Teacher,需要由 SCHOOL 解除关系后,才能删除 Teacher。但是可以直接删除 SCHOOL,因为 SCHOOL 是关系维护端,删除 SCHOOL 时,会先解除 SCHOOL 和 Teacher 的关系,再删除 Teacher。
*/
/*
1、关系维护端,负责多对多关系的绑定和解除
2、@JoinTable注解的name属性指定关联表的名字,joinColumns指定外键的名字,关联到关系维护端(School)
3、inverseJoinColumns指定外键的名字,要关联的关系被维护端(Teacher)
4、其实可以不使用@JoinTable注解,默认生成的关联表名称为主表表名+下划线+从表表名,
即表名为SCHOOL_TEACHER
关联到主表的外键名:即school_id
关联到从表的外键名:即teacher_id
主表就是关系维护端对应的表,从表就是关系被维护端对应的表*/
@ManyToMany
@JoinTable(name = "SCHOOL_TEACHER",joinColumns = @JoinColumn(name = "school_id"),
inverseJoinColumns = @JoinColumn(name = "teacher_id"))
private List<Teacher> teachers;
}