cascade屬性通常在one-to-many關係裡應用
阿新 • • 發佈:2019-01-24
在資料庫裡,進行增加、修改、刪除記錄的時候,經常會涉及到父子關係的表。
例如:有省份表和城市表,其中城市表有一個外來鍵province_id引用到省份表的主鍵。這樣,可以把省份表看成是父表,把城市表看成是子表,城市表記錄的存在依賴於省份表的記錄。(文中提到的例子,所有的程式碼在附件裡都有,所以這裡的描述從簡)
一、在MySQL裡的cascade
以下直接在MySQL的控制檯操作省份表和城市表
在省份表增加一條“廣東”的記錄,在城市表增加一條“廣州”的記錄,並且把“廣州”的外來鍵引用到“廣東”的主鍵。“廣州”的存在依賴於“廣東”,如果刪除省份表的“廣東”,將會影響到城市表的“廣州”。根據城市表的外來鍵約束的on delete設定,有如下三種情況:
1、外來鍵沒有on delete的設定:當刪除“廣東”的時候,MySQL會報錯,刪除失敗。
2、外來鍵設定為on delete cascade:當刪除“廣東”的時候,同時把“廣州”也刪除。
3、外來鍵設定為on delete set null:當刪除“廣東”的時候,“廣州”的外來鍵province_id會被自動設定為null,即“廣州”脫離了對“廣東”的依賴關係。
二、在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屬性,有以下幾種情況:
1、沒有設定cascade屬性
用方法addInNoCascade()增加記錄“廣東”和“廣州”(方法在類CityManager裡,以下同),再用方法delete()刪除“廣東”,將會出現異常,系統會說因為“廣東”被城市表外來鍵關聯了而不能刪除。用SQL建表時,已經把外來鍵設為on delete cascade,怎麼不能把“廣東”刪除的同時,級聯刪除“廣州”呢?用MyEclipse檢視城市表,發現有兩個外來鍵,如圖所示:
第2個外來鍵是用SQL建表時生成的,設定了on delete cascade;而第1個外來鍵應該是用Hibernate操作資料庫時,Hibernate自動建立的。第1個外來鍵的On delete被設定為No action,因此刪除“廣東”的時候,受到這個外來鍵的限制,導致刪除失敗。
2、設定cascade屬性為delete-orphan
在對映檔案Province.hbm.xml中,在one-to-many關係對應的Set裡,設定cascade="delete-orphan",此功能與MySQL裡設定外來鍵設定為on delete cascade相同。再用方法delete()刪除“廣東”,刪除成功。即是,設定cascade為delete-orphan以後,對刪除父表記錄的時候,會同時刪除子表的相關記錄。
3、設定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屬性。
例如:有省份表和城市表,其中城市表有一個外來鍵province_id引用到省份表的主鍵。這樣,可以把省份表看成是父表,把城市表看成是子表,城市表記錄的存在依賴於省份表的記錄。(文中提到的例子,所有的程式碼在附件裡都有,所以這裡的描述從簡)
一、在MySQL裡的cascade
以下直接在MySQL的控制檯操作省份表和城市表
在省份表增加一條“廣東”的記錄,在城市表增加一條“廣州”的記錄,並且把“廣州”的外來鍵引用到“廣東”的主鍵。“廣州”的存在依賴於“廣東”,如果刪除省份表的“廣東”,將會影響到城市表的“廣州”。根據城市表的外來鍵約束的on delete設定,有如下三種情況:
1、外來鍵沒有on delete的設定:當刪除“廣東”的時候,MySQL會報錯,刪除失敗。
2、外來鍵設定為on delete cascade:當刪除“廣東”的時候,同時把“廣州”也刪除。
3、外來鍵設定為on delete set null:當刪除“廣東”的時候,“廣州”的外來鍵province_id會被自動設定為null,即“廣州”脫離了對“廣東”的依賴關係。
二、在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屬性,有以下幾種情況:
1、沒有設定cascade屬性
用方法addInNoCascade()增加記錄“廣東”和“廣州”(方法在類CityManager裡,以下同),再用方法delete()刪除“廣東”,將會出現異常,系統會說因為“廣東”被城市表外來鍵關聯了而不能刪除。用SQL建表時,已經把外來鍵設為on delete cascade,怎麼不能把“廣東”刪除的同時,級聯刪除“廣州”呢?用MyEclipse檢視城市表,發現有兩個外來鍵,如圖所示:
第2個外來鍵是用SQL建表時生成的,設定了on delete cascade;而第1個外來鍵應該是用Hibernate操作資料庫時,Hibernate自動建立的。第1個外來鍵的On delete被設定為No action,因此刪除“廣東”的時候,受到這個外來鍵的限制,導致刪除失敗。
2、設定cascade屬性為delete-orphan
在對映檔案Province.hbm.xml中,在one-to-many關係對應的Set裡,設定cascade="delete-orphan",此功能與MySQL裡設定外來鍵設定為on delete cascade相同。再用方法delete()刪除“廣東”,刪除成功。即是,設定cascade為delete-orphan以後,對刪除父表記錄的時候,會同時刪除子表的相關記錄。
3、設定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屬性。