Inverse屬性
Inverse屬性:表示控制權是否轉移..
- true:控制權已轉移【當前一方沒有控制權】
- false:控制權沒有轉移【當前一方有控制權】
Inverse屬性,是在維護關聯關係的時候起作用的。只能在“一”的一方中使用該屬性!Inverse屬性的預設值為fasle,也就是當前一方是有控制權的
從一下的幾個方面看看Inverse在維護關聯關係時是否起作用:
- 儲存資料
- 獲取資料
- 解除關聯關係
- 刪除資料對關聯關係的影響
儲存資料
將inverse屬性設定為ture,使dept沒有控制權
<!--維護關係的是Set集合,對應employee表-->
<set cascade="save-update" name="set" table="employee" inverse="true">
複製程式碼
執行儲存資料操作時,發現Hibernate只執行了三條SQL語句。employee表的外來鍵並沒有資料
結論:如果設定控制反轉,即inverse=true, 然後通過部門方維護關聯關係。在儲存部門的時候,同時儲存員工, 資料會儲存,但關聯關係不會維護。即外來鍵欄位為NULL
查詢資料
設定inverse屬性為true,那麼部門一方是沒有控制權的。
<set cascade="save-update" name="set" table="employee" inverse="true">
複製程式碼
我們在檢視資料的時候,發現inverse屬性對查詢資料是沒有影響的
//查詢出Dept物件
Dept de = (Dept) session.get(Dept.class, 1);
System.out.println(dept.getDeptName());
System.out.println("-----------");
//用到的時候再查詢資料庫,Hibernate的懶載入【後面會講解】
System.out.println(de.getSet());
複製程式碼
解除關聯關係
部門和員工是存在外來鍵的聯絡的,我們接下來看看inverse屬性對於解除關聯關係有沒有影響
- 當部門一方有許可權時,即inverse屬性為false
//查詢部門id為1的資訊
Dept dept1 = (Dept) session.get(Dept.class, 1);
//清除關聯資訊
dept1.getSet().clear();
複製程式碼
可以解除關聯關係,employee的外來鍵欄位被設定為NULL了
- 當部門一方沒有許可權時,即inverse屬性為true
//查詢部門id為2的資訊
Dept dept1 = (Dept) session.get(Dept.class, 2);
//清除關聯資訊
dept1.getSet().clear();
複製程式碼
不能解除關聯關係
刪除資料對關聯關係的影響
- 當部門一方有許可權時,即inverse屬性為false
//查詢部門id為2的資訊
Dept dept1 = (Dept) session.get(Dept.class, 2);
//刪除部門2
session.delete(dept1);
複製程式碼
當有控制權的時候可以刪除資料,先把外來鍵設定為NULL,再刪除資料!
- 當部門一方沒有許可權時,即inverse屬性為true
//查詢部門id為1的資訊
Dept dept1 = (Dept) session.get(Dept.class, 1);
//刪除部門1
session.delete(dept1);
複製程式碼
直接丟擲異常,說該部門擁有外來鍵,不能刪除資料!
cascade屬性
cascade表示級聯的意思,簡單來說就是操作某一屬性時,對其他關聯欄位的影響
casecade屬性不像inverse屬性只能在“一”的一方設定,它可以在“一”的一方也可以在“多”的一方設定
cascade有這麼幾個值
- none 不級聯操作, 預設值
- save-update 級聯儲存或更新
- delete 級聯刪除
- save-update,delete 級聯儲存、更新、刪除
- all 同上。級聯儲存、更新、刪除
級聯儲存
級聯儲存有什麼用呢???我們來看個例子:
- 如果在儲存物件的時候,沒有把相關的物件也一併儲存進資料庫,會出現錯誤。
- 因為它會發現dept是有外來鍵的,而外來鍵又是一個物件來儲存著,這個物件在資料庫表中並沒有存在,因此會丟擲異常
//建立物件
Dept dept = new Dept();
dept.setDeptName("開發部");
Employee zs = new Employee();
zs.setEmpName("張珊");
zs.setSalary(1111);
Employee ls = new Employee();
ls.setEmpName("李四");
ls.setSalary(2222);
//維護關係
dept.getSet().add(zs);
dept.getSet().add(ls);
//儲存dept物件
session.save(dept);
複製程式碼
如果我們在dept中設定了級聯儲存,那麼Hibernate就會知道:儲存dept的資料時,發現dept了外來鍵,也把dept外來鍵的物件儲存在資料庫之中
<set name="set" table="employee" cascade="save-update" >
複製程式碼
級聯刪除
級聯刪除,這個對於我們來說風險太大了,如果刪除了某些資料,會把另外有關聯的資料也刪除...在實際中我們一般不使用!
- 在沒有設定級聯刪除的時候,我們試試刪除dept
//刪除部門為3的記錄
Dept dept1 = (Dept) session.get(dept.getClass(), 3);
session.delete(dept1);
複製程式碼
它會先把3的外來鍵對應的記錄刪除,再刪除部門的資料
- 在設定級聯刪除的時候,我們試試刪除dept
<set name="set" table="employee" cascade="save-update,delete" >
複製程式碼
- 級聯刪除資料
//刪除部門為4的記錄
Dept dept1 = (Dept) session.get(dept.getClass(), 4);
session.delete(dept1);
複製程式碼
我們發現資料相關聯的資料都沒有了
cascade和inverse同時使用
上面我們已經把cascade和inverse都介紹一遍了,那麼cascade和inverse同時使用會怎麼樣呢???我們來測試一下
- 設定dept沒有控制權,但設定級聯儲存、刪除
<set name="set" table="employee" cascade="save-update,delete" inverse="true" >
複製程式碼
- 新增一個dept物件
//新增一個dept物件
session.save(dept);
複製程式碼
如果我們單單設定了inverse屬性為true,那麼資料庫中肯定是不能維護關聯關係的【這裡我們已經測試了】
但是呢,現在也設定了級聯儲存,級聯儲存是否可以讓該物件相關的關聯關係一併儲存在資料庫中的。
我們來看看結果:
inverse的優先順序是比cascade的優先順序要高的,因此設定了inverse屬性為true,那麼cascade就無效了。
參考詳細博文:
http://www.cnblogs.com/whgk/p/6135591.html
ascade和inverse總結
上面的測試都是通過幾個方面的,看起來有點多,因此我們總結一下
inverse屬性
inverse屬性只能在“一”的一方中設定。inverse=false表示有控制權,inverse=ture表示沒有控制權
- 在儲存關聯資訊時
- 有控制權--->可以儲存相對應的關聯資料
- 沒有控制權--->資料會儲存,但是關聯關係沒有維護,也就是外來鍵列為NULL
- 在查詢資料時
- 有無控制權對查詢資料沒有任何影響
- 在解除關聯關係時
- 有控制權--->可以解除關聯關係
- 沒有控制權--->不能解除關聯關係,不會生成update語句,也不會報錯
- 在刪除資料時對關聯關係的影響
- 有控制權--->將外來鍵的值設定為NULL,隨後刪除資料
- 沒有控制權--->如果刪除的記錄有被外來鍵引用,會報錯,違反主外來鍵引用約束,如果刪除的記錄沒有被引用,可以直接刪除。
多對多關係的時候也是一樣的,只不過多對多的關聯關係是在中間表中
cascade屬性
cascade有這麼幾個值:
- none 不級聯操作, 預設值
- save-update 級聯儲存或更新
- delete 級聯刪除
- save-update,delete 級聯儲存、更新、刪除
- all 同上。級聯儲存、更新、刪除
我們可能使用到的往往是:save-update這個值,因為級聯刪除的風險太大了!
- 級聯儲存
- 沒有設定級聯儲存-->如果單單儲存一個物件,而物件又存在外來鍵時,那麼就會丟擲異常
- 設定了級聯儲存-->那麼就可以將物件以及有關聯關係的物件一併儲存
- 級聯刪除
- 沒有設定級聯刪除-->在刪除資料的時候,會把外來鍵的欄位設定為NULL,再刪除當前一方的記錄
- 設定了級聯刪除-->把物件有關聯關係的記錄都刪除了
如果cascade和inverse同時設定時:
- inverse屬性優先順序是要比cascade要高的,如果inverse屬性設定了true,那麼cascade就無效了!
如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關注微信公眾號:Java3y