1. 程式人生 > >hibernate中 cascade屬性詳解

hibernate中 cascade屬性詳解

-m hibernate 發現 執行效率 pda 不一定 () 程序執行效率 刪除

配置關聯時,我們考慮兩點:程序執行效率和實際業務需要,前面的例子中無論是單向的關聯還是雙向的關聯,我們都要分別對實體類使用session.save()才能將數據保存至數據庫。
問題:如果保存數據非常多,那編碼是一件恐怖的事情。
有沒有簡單的方法呢?
將<set>標簽cascade=all
總結:我們只對district對象執行了持久化操作,但是通過sql語句,我們發現street執行了持久啊操作,這就是cascade屬性的作用。當設置cascade屬性不none時,Hibernate會持久化所關聯的對象。


1.all :對象所有操作進行級聯操作 save,update,delete
2.save-update : 執行保存和更改操作時進行級聯操作
3.delete : 執行刪除操作時進行級聯操作
4.none : 對所有操作不進行級聯操作 默認

cascade屬性的設置往往會帶來性能上的變動,請謹慎設置。
例如:對district對象進行保存或更改操作時,district對象不一定有關聯的street對象,或street對象不一定也需要更新,但是刪除district對象時同時刪除它所關聯的street對象
因此:將cascade屬性設置為all是不恰當的,應該設置為delete

Hibernate: insert into district (name, id) values (?, ?)
Hibernate: insert into street (name, district_id, id) values (?, ?, ?)
Hibernate: update street set district_id=? where id=?
1.第一條語句:比較好理解,插入新的區數據
2.第二天語句:這裏為什麽出現insert街道呢?我們並沒有編寫session.save(street)?
答案:其實我們在district端設置了級聯更新(cascade=”all”)
也即是說,當HIbernate在向district插入”新“對象記錄時,會檢查“district”對象所關聯的屬性(就是<set>對應的屬性)是否發生變化,如果發生變化就按設定的內容進行操作。因為調用了district.getStreet().add(street),所有Hibenate插入district時候,也一同把它所關聯的瞬時狀態的對象一同插入到對應的表中區。

Hibernate: update street set district_id=? where id=?
3.第三條語句:是update語句,為什麽重復更新記錄?
答:Hibernate將district與street之間的關聯交由district來維持,就district而言,它要先儲存自己,然後儲存它所包括的多個street,之後對每一個street更新(update)對自己(district)的關聯。
就district而言,它並不知道它所包括的street是不是已存儲的對象,或者即使是已存儲對象,也不知道street表格上的district_id是不是參考至district表格的id
所以,它必須針對自己所有包括的street對象進行更新,以確保street表格上的district_id是指向自己的。

正因為如此,所以Hibernate“怕”在進行”district.getStreet().add(street)”這樣操作時,出現意外情況(如street.getClss=null,street沒有所屬的區)
存在外鍵不一致的情況。所有出現了這條多余的update語句。
也就是由one-to-many中一的一方(district端)主動維護外鍵,以保證所有包含district對象的集合裏的所有street對象都要與自己(district)有外鍵關聯。
通俗講:每年開學新生報到,班級老師主動邀請同學,而不是同學自己來報到。可想而知效率怎麽樣?
Hiberate有沒有提供解決這種情況的辦法呢?
當然有:那就是設置inverse屬性!!

hibernate中 cascade屬性詳解