Hibernate @OneToMany 及 @Cascade級聯操做

前言

image.png

由圖中能夠看出實體間關係:一對多(@OneToManygit

在實際開發場景中,刪除員工老闆不會被刪除,老闆被刪除了員工確定要刪除github

由此,就會使用級聯操做,在一對多關係中,@Cascade屬性(級聯)只設置「一」的一方便可,外鍵由「多」的一方進行維護。數據庫

@ManyToOne和@OneToMany 註解

  1. ManyToOne(多對一)單向:不產生中間表,但能夠用@Joincolumn(name="  ")來指定生成外鍵的名字,外鍵在多的一方表中產生。
  2. OneToMany(一對多)單向:會產生中間表,此時能夠用@onetoMany @Joincolumn(name=" ")避免產生中間表,而且指定了外鍵的名字(別看@joincolumn在一中寫着,但它存在在多的那個表中)
  3. OneToMany , ManyToOne 雙向(兩個註解一塊兒用的):若是不在@OneToMany中加mappedy屬性就會產生中間表。

cascade屬性: 指定級聯操做的行爲(可多選)

  • CascadeType.PERSIST:級聯新增(又稱級聯保存):對A對象保存時也會對B對象進行保存。而且,只有A類新增時,會級聯B對象新增。若B對象在數據庫存在則拋異常。對應EntityManagerpresist方法。
  • CascadeType.MERGE:級聯合並(級聯更新):指A類新增或者變化,會級聯B對象(新增或者變化)。對應EntityManagermerge方法。
  • CascadeType.REMOVE:級聯刪除:只有A類刪除時,會級聯刪除B類,即在設置的那一端進行刪除時,另外一端纔會級聯刪除。對應EntityManagerremove方法。
  • CascadeType.REFRESH:級聯刷新:獲取A對象時也從新獲取最新的B對象。對EntityManagerrefresh(object)方法。即會從新查詢數據庫裏的最新數據(用的比較少)
  • CascadeType.DETACH:級聯分離。
  • CascadeType.ALL:級聯全部操做。

示例(以級聯保存及刪除爲例)

Boss老闆實體:app

@Entity  
public class Boss {  
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    private Long id;  
    
    private String name;  
    
    @OneToMany(mappedBy = "boss")  
    private List<Staff> staffList;
}

Staff員工實體:測試

@Entity
public class Staff { 
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    private Long id;  
  
    private String name;  
  
    @ManyToOne  
    private Boss boss;
}

不添加任何級聯

執行save保存操做,結果以下spa

老闆表:code

image.png

員工表:對象

image.png

執行的SQL:blog

insert into boss (name) values ('張老闆')

PERSIST:級聯新增(又稱級聯保存)

@OneToMany(mappedBy = "boss", cascade = CascadeType.PERSIST)  
private List<Staff> staffList;

執行save保存操做,結果以下開發

老闆表:

image.png

員工表:

image.png

員工已經級聯保存,可是員工表中的 boss_id倒是空,可見級聯是直接將 set中的對象持久化到數據庫,而並無對關係進行維護(須要手動去維護)。

執行的SQL:

insert into boss (name) values ('張老闆')
insert into staff (boss_id, name) values (1, '員工一')
insert into staff (boss_id, name) values (1, '員工二')

直接在數據庫中執行SQL關係是維護好的

REMOVE:級聯刪除

@OneToMany(mappedBy = "boss", cascade = CascadeType.REMOVE)  
private List<Staff> staffList;

執行delete保存操做,結果以下

老闆表:
image.png

員工表:

image.png

執行的SQL

select boss0_.id as id1_0_0_, boss0_.name as name2_0_0_ from boss boss0_ where boss0_.id=1

select stafflist0_.boss_id as boss_id3_2_0_, stafflist0_.id as id1_2_0_, stafflist0_.id as id1_2_1_, stafflist0_.boss_id as boss_id3_2_1_, stafflist0_.name as name2_2_1_ from staff stafflist0_ where stafflist0_.boss_id=1

delete from staff where id=1
delete from staff where id=2
delete from boss where id=1
老闆表該條記錄刪除,同時員工表中的記錄也被級聯刪除。

代碼

級聯小測試代碼

相關文章
相關標籤/搜索