Hibernate【inverse和cascade屬性】知識要點

Java3y發表於2018-03-08

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

相關文章