假设有俩个实体用户和专业课(关系:多对多)git
现需求用户能够新增编辑专业课,但在专业课模块中一样能够新增用户和编辑用户github
Course:数据库
@Entity public class Course implements YunzhiEntity { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Long id; private String name; @ManyToMany(mappedBy = "courses") private List<User> users; public Course() {} }
User:app
@Entity public class User implements YunzhiEntity { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Long id; private String name; @Column(nullable = false, unique = true) private String username; @Column(nullable = false) private String password; @ManyToMany private List<Course> courses; public User() {} }
思路
新增:新增比较简单,直接操做中间表把数据保存到中间表
更新:更新变向的理解也就是新增,因此就先把原来的删除在新增
因为mappedBy
映射关系是由一方维护,因此须要后台单独处理中间表中的数据测试
实现以下:spa
在更新中把中间表相关数据先移出,而后在从新创建关系,以下:hibernate
将新的数据,保存到中间表中。在此使专业课和用户从新创建新的关系code
在新增时只需save
时在调用updateUsersOfCourse(Course course)
这个方法就能够blog
这种实现方式看起来比较笨拙,潘老师提示,
Hibernate
不会这么傻,须要这么麻烦,确定有新的实现方式
使用Hibernate
的关联删除,去除手动操做中间表的代码,看起来更简洁,更新更容易理解文档
修改实体 Course实体与User实体,不使用由一方维护的mappedBy
来映射关系,以下:
Course:
@Entity public class Course implements YunzhiEntity { ...... @ManyToMany(cascade ={CascadeType.REMOVE}) @JoinTable(name="User_Courses",joinColumns=@JoinColumn(name="Courses_id"),inverseJoinColumns=@JoinColumn(name="Users_id")) @JsonView(users.class) private List<User> users; ...... }
User:
@Entity public class User implements YunzhiEntity { ...... @ManyToMany(cascade ={CascadeType.REMOVE}) @JoinTable(name="User_Courses",joinColumns=@JoinColumn(name="Users_id"),inverseJoinColumns=@JoinColumn(name="Courses_id")) @JsonView(courses.class) private List<Course> courses; ...... }
使用mappedBy
来创建俩实体间的关系,它是一方来维护的,就像 ‘A中有B或B中有A’,是单向的。因此直接使用cascade ={CascadeType.REMOVE}
级联删除,很差使;
向上述例子,‘A中有B,B中有A’,是双向的。“双向结构+双向维护外键”。这个双向维护外键,指不管是对course.users
仍是user.courses
修改,保存后均会影响中间表的数据。
参考文档 stackoverflow
创建三个实体 A B C
A:B = ManyToMany(上述新方式)
A:C = ManyToMany(普通的方式mappedBy
)
一样执行多对多的更新操做。对比两个更新最终生成的SQl
语句有何不一样。
A:
B:
C:
源码地址 github
使用Postman
向后台发送请求,执行更新操做,获得SQl
语句,以下:
上述新方法生成的SQL
语句:
普通的方式mappedBy
生成的SQL
语句:
发现普通的方式mappedBy
生成的SQL
语句比较多,多的是更新时操做中间表SQL
,为数据库增长了无形的压力。