JPA之级联关系@OneToMany 和 @ManyToMany

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;

}
发布了19 篇原创文章 · 获赞 1 · 访问量 284

猜你喜欢

转载自blog.csdn.net/XSemperFI/article/details/103172571