數據庫裏的cascade的用法,Mysql和Hibernate裏面是不相同。sql
在數據庫裏,進行增長、修改、刪除記錄的時候,常常會涉及到父子關係的表。
例如:有省份表和城市表,其中城市表有一個外鍵province_id引用到省份表的主鍵。這樣,能夠把省份表當作是父表,把城市表當作是子表,城市表記錄的存在依賴於省份表的記錄。(文中提到的例子,全部的代碼在附件裏都有,因此這裏的描述從簡)
1、在MySQL裏的cascade
如下直接在MySQL的控制檯操做省份表和城市表
在省份表增長一條「廣東」的記錄,在城市表增長一條「廣州」的記錄,而且把「廣州」的外鍵引用到「廣東」的主鍵。「廣州」的存在依賴於「廣東」,若是刪除省份表的「廣東」,將會影響到城市表的「廣州」。根據城市表的外鍵約束的on delete設置,有以下三種狀況:
一、外鍵沒有on delete的設置:當刪除「廣東」的時候,MySQL會報錯,刪除失敗。
二、外鍵設置爲on delete cascade:當刪除「廣東」的時候,同時把「廣州」也刪除。
三、外鍵設置爲on delete set null:當刪除「廣東」的時候,「廣州」的外鍵province_id會被自動設置爲null,即「廣州」脫離了對「廣東」的依賴關係。
2、在Hibernate裏的cascade
如下用Hibernate來操做省份表和城市表
首先,在hibernate.cfg.xml文件配置好鏈接MySQL數據庫的相關屬性(請在那裏修改登錄數據庫的密碼)。而後,爲省份表和城市表添加相關的POJO類和XML映射文件。用SQL語句建表(在附件的test_cascade.sql裏),城市表有一個外鍵province_id引用到省份表的主鍵,並把這個外鍵設置爲on delete cascade。這個外鍵約束,在Hibernate變成了雙向的映射關係:City類有一個類型爲Province的province屬性,關聯到省份表,在映射文件中是many-to-one的關係;Province類有一個Set<City>的cities屬性,關聯到城市表,在映射文件中是one-to-many的關係。
在Hibernate的映射文件裏,一樣能夠設置cascade屬性來控制父子關係。一般在父表設置cascade屬性,有如下幾種狀況:
一、沒有設置cascade屬性
用方法addInNoCascade()增長記錄「廣東」和「廣州」(方法在類CityManager裏,如下同),再用方法delete()刪除「廣東」,將會出現異常,系統會說由於「廣東」被城市表外鍵關聯了而不能刪除。用SQL建表時,已經把外鍵設爲on delete cascade,怎麼不能把「廣東」刪除的同時,級聯刪除「廣州」呢?用MyEclipse查看城市表,發現有兩個外鍵,如圖所示:
第2個外鍵是用SQL建表時生成的,設置了on delete cascade;而第1個外鍵應該是用Hibernate操做數據庫時,Hibernate自動創建的。第1個外鍵的On delete被設置爲No action,所以刪除「廣東」的時候,受到這個外鍵的限制,致使刪除失敗。
二、設置cascade屬性爲delete-orphan
在映射文件Province.hbm.xml中,在one-to-many關係對應的Set裏,設置cascade="delete-orphan",此功能與MySQL裏設置外鍵設置爲on delete cascade相同。再用方法delete()刪除「廣東」,刪除成功。便是,設置cascade爲delete-orphan之後,對刪除父表記錄的時候,會同時刪除子表的相關記錄。
三、設置cascade屬性爲all
cascade的屬性,除了能夠是delete-orphan,還能夠是create、update、delete、all等等。all表明除 delete-orphan之外的全部屬性值,當設置cascade爲all之後,對父表記錄的增長、修改操做,會影響到子表的相關記錄。
在映射文件Province.hbm.xml中,在one-to-many關係對應的Set裏,設置cascade="all"。用方法 addInCascadeOfAll()增長記錄「廣東」,方法裏只有save「廣東」,並無save「深圳」,只是用屬性關聯了「廣東」和「深圳」的關係。結果顯示,深圳也被添加到數據庫裏,這就是cascade="all"的做用,使對父表的操做影響到子表。
注意:A、delete-orphan是一個特別的屬性值,只能應用在one-to-many關係的cascade屬性。B、cascade屬性一般在one-to-one和one-to-many關係裏應用,不推薦在many-to-one或者many-to- many關係裏應用。
3、總結
一、MySQL裏設置cascade和在Hibernate設置cascade是不一樣的。在MySQL裏設置了cascade,並不能對Hibernate的操做起到做用,緣由是Hibernate自動爲子表添加了外鍵。
數據庫
二、使用級聯(cascade)功能,方便了數據庫的操做,使得操做一個表的記錄會影響到其餘表的記錄。可是,級聯功能會帶來安全隱患。特別是在 Hibernate裏,修改一個POJO對象的映射引用屬性,會致使該引用屬性所對應的POJO對象受到影響。例如,把「廣東」的 Set<City>類型的cities屬性清空(即對集合Set調用clear()方法),則會致使把引用「廣東」的「深圳」刪除了。所以,使用級聯功能時要當心謹慎。安全
原文地址:不詳。spa