標籤:pre lin 責任 關係 data- 總結 設立 成功 多對多
學習hibernate的時候對級聯關係的概念老是分不清楚,尤其是cascade、inverse傻傻分不清。以下通過範例來簡單說明。
準備工作:
首先建立資料庫,建立兩張表:
教室表classes (欄位此處省)
學生表student(欄位此處省)
教室與學生是一對多的關係。 然後建立項目,加入hibernate對兩張表的支援。
1.cascade
cascade表示級聯操作。即兩個實體間存在級聯關係(一個類是還有一個類中的屬性)時,當儲存、更新或刪除一個實體時,是否對關聯的實體做出相應操作(資料庫操作),比如:
儲存班級級聯儲存學生:
在Classes.hbm.xml設定檔裡做例如以下改動:
如今運行例如以下的代碼:
這樣在儲存classes的時候的時候會自己主動在資料庫中加入兩個新學生。
說明:
- 在hibernate中,通過session.save方法儲存一個持久化對象這樣的方式稱為顯示儲存。
- 在hibernate中,通過級聯的方式來操作一個對象。這樣的方式稱為隱式操作。
- 對student對象進行了隱式的儲存操作,是由於student是一個暫時狀態的對象。在資料庫中沒有相應的記錄,所以應該對student運行insert語句
更新班級串聯更新學生:
說明:
- 在運行110行代碼的時候,產生了例如以下的sql語句
- 運行114行代碼的時候。產生了例如以下的sql語句
該update語句產生了3條,由於該班級中有3個學生,3個學生的屬性同一時候發生改變。
- 沒有發出更新classes的update語句。由於classes的屬性沒有發生改變。
刪除班級串聯刪除學生:
設定Classes.hbm.xml的Cascade為Delete
此時此classes包括的所以的student都一併刪除了。注意在假設不設定串聯刪除則無法刪除被外鍵引用的對象。
總結
Cascade:
- Save-update
在session.save/update一個對象的時候,級聯操作關聯對象,關聯對象或者運行save語句或者運行update語句或者什麼都不運行
- Delete
在session.delete一個對象的時候,串聯刪除關聯對象
- All
Save-update和delete的結合
2.inverse
inverse屬性用於指示本方是否參與維護關係。設為true時不維護,設為false時維護。
此處的關係是指關聯兩張表的
外鍵或者關係表欄位。
本屬性一般設定於一對多關聯性中的一端。而且設定為false。由於若由一端負責維護,每次更新完一端資料,都會去尋找於一端有關係的多段表中的行,並更新其外鍵欄位。而由多端維護時。由於一端對象是多端對象的屬性欄位,所以,每次更新多端後提交資料。都會自己主動更新該欄位(若有更新時),這樣比較方便。
3.Cascade與inverse的差別 student 與 classes
cascade和外鍵沒有關係,在student表中。sid、name、description和cascade有關係,可是cid和cascade沒有關係。
inverse僅僅和cid有關係。假設維護。則發出update語句(更新外鍵的sql語句)。假設不維護,則無論。
- inverse屬性預設是false的,就是說關係的兩端都來維護關係。當設定inverse=”true”時則不維護
4.僅僅有inverse沒有cascade的時候:
對於資料中不存在的classes和student時:把student設定給classes時,僅僅儲存classes而不直接儲存student時僅僅會運行insert classes的方法而對於student(即使不存在)不會insert而僅僅會update(由於在同一個事物中所以終於導致classes也不能被儲存)
當要儲存的classes設定的student是資料庫中存在的時候,會對其運行update方法,而假設對classes設定了cascade,則會對不存在的student設定insert:
當給classes設定inverse=”true”時。則表示classes不維護和student的外鍵關係。此時當刪除一個classes時,由於classes不維護與student的關係,顧不會發出update語句所以會報錯。而假設classes沒有設定inverse=”true”,即inverse=”false”,則說明classes維護關係。故當刪除classes時會發出update student的語句,故能夠刪除成功.
5.正確的設定inverse
我們說inverse設立不當會導致效能低下,事實上是說inverse設立不當,會產生多餘反覆的SQL語句甚至致使JDBC exception的throw。
這是我們在建立實體類別關係時必鬚鬚要關注的地方。
一般來說,inverse=true是推薦使用,雙向關聯中兩方都設定 inverse=false的話,必會導致兩方都反覆更新同一個關係。
可是假設兩方都設立inverse=true的話,兩方都不維護關係的更新,這也是不行的,好在一對多中的多端:one-to-many預設是inverse=false,避免了這樣的錯誤的產生。可是多對多就沒有這個預設設定了,所以非常多人常常在多對多的兩端都使用inverse=true,結果導致串連表的資料根本沒有記錄,就是由於他們兩方都沒有責任維護關係。所以說,雙向關聯中最好的設定是一端為inverse=true。一端為inverse=false。一般inverse=false會放在多的一端,那麼有人提問了。 many-to-many兩邊都是多的。inverse究竟放在哪兒?事實上hibernate建立多對多關係也是將他們分離成兩個一對多關聯性,中間串連一個串連表。
所以通用存在一對多的關係。也能夠這樣說:一對多是多對多的基本組成部分。
具體解釋Hibernate中cascade與inverse