假設有倆個實體用戶和專業課(關係:多對多)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
,爲數據庫增長了無形的壓力。