級聯屬性

hibernate constrained屬性


舉個例子你就能知道了!
 

A表(a1,b1,c1)      B表(a2,b2)
 a1   b1   c1       a2    b2
 01   數學 95       01    張三
 02   語文 90       02    李四
 03   英語 80       04    王五
 
select A.*,B.* from A inner join B on(A.a1=B.a2)
 結果是:
 a1   b1   c1       a2    b2
 01   數學 95       01    張三
 02   語文 90       02    李四

 select A.*,B.* from A left outer join B on(A.a1=B.a2)
 結果是:
 a1   b1   c1       a2    b2
 01   數學 95       01    張三
 02   語文 90       02    李四
 03   英語 80       NULL  NULL

 select A.*,B.* from A right outer join B on(A.a1=B.a2)
 結果是:
 a1   b1   c1       a2    b2
 01   數學 95       01    張三
 02   語文 90       02    李四
 NULL NULL NULL     04    王五

 select A.*,B.* from A full outer join B on(A.a1=B.a2)
 結果是:
 a1   b1   c1       a2    b2
 01   數學 95       01    張三
 02   語文 90       02    李四
 03   英語 80       NULL  NULL
 NULL NULL NULL     04    王五



4.2. 級聯(cascade)屬性的作用:

      4.2.1 只有“關係標記”纔有cascade屬性:many-to-one,one-to-one ,any,

                set(map, bag, idbag, list, array) + one-to-many(many-to-many)


     4.2.2 級聯指的是當主控方執行操作時,關聯對象(被動方)是否同步執行同一操作。

              pojo和它的關係屬性的關係就是“主控方 -- 被動方”的關係,如果關係屬性是一個set,那麼被動方就是set中的一個一個元素,。

              比如:學校(School)有三個屬性:地區(Address),校長(TheMaster)和學生(Set, 元素爲Student)

              執行session.delete(school)時,級聯決定是否執行session.delete(Address),session.delete(theMaster),

              是否對每個aStudent執行session.delete(aStudent)。

              extend:這點和inverse屬性是有區別的。見4.3.


4.2.3 一個操作因級聯cascade可能觸發多個關聯操作。前一個操作叫“主控操作”,後一個操作叫“關聯操作”。

          cascade屬性的可選值:

          all : 所有情況下均進行關聯操作。

          none:所有情況下均不進行關聯操作。這是默認值。

          save-update:在執行save/update/saveOrUpdate時進行關聯操作。

           delete:在執行delete時進行關聯操作。


           具體執行什麼“關聯操作”是根據“主控操作”來的:
            “主控操作”        “關聯操作”
             session.saveOrUpdate --> session.saveOrUpdate (執行saveOrUpdate實際上會執行save或者update)
             session.save ----> session.saveOrUpdate
             session.udpate --> session.saveOrUpdate
             session.delete --> session.delete

4.2.4 主控操作和關聯操作的先後順序是“先保存one,再保存many;先刪除many,再刪除one;先update主控方,再update被動方”

          對於one-to-one,當其屬性constrained="false"(默認值)時,它可看作one-to-many關係;
          當其屬性constrained="true"時,它可看作many-to-one關係;
          對many-to-many,它可看作one-to-many。

          比如:學校(School)有三個屬性:地區(Address),校長(TheMaster,其constrained="false")和學生(Set, 元素爲Student)
          當執行session.save(school)時,
                    實際的執行順序爲:session.save(Address);
                                                   session.save(school);
                                                   session.save(theMaster);
                                                    for( 對每一個student ){
                                                             session.save(aStudent);
                                                    }

         當執行session.delete(school)時,
                 實際的執行順序爲:session.delete(theMaster);
                                        for( 對每一個student ){
                                               session.delete(aStudent);
                                             }
                                              session.delete(school);
                                              session.delete(Address);

         當執行session.update(school)時,
                 實際的執行順序爲:session.update(school);
                                                session.saveOrUpdate(Address);
                                                session.saveOrUpdate(theMaster);
                                                for( 對每一個student ){
                                                session.saveOrUpdate(aStudent);

                                                }


注意:update操作因級聯引發的關聯操作爲saveOrUpdate操作,而不是update操作。
           saveOrUpdate與update的區別是:前者根據操作對象是保存了還是沒有保存,而決定執行update還是save

extends: 實際中,刪除學校不會刪除地區,即地區的cascade一般設爲false
              另外,many-to-many關係很少設置cascade=true,而是設置inverse=false。這個反映了cascade和inverse的區別。見4.3

4.2.6 cascade的默認值爲false,所以inverse屬性默認會進行“關聯更新”。


4.2.7 總結:級聯(cascade)就是操作一個對象時,對它的屬性(其cascade=true)也進行這個操作。





【cseu】:

4.3 inverse和cascade的比較

       這兩個屬性本身互不影響,但起的作用有些類似,都能引發對關係表的更新。

4.3.1 inverse只對set+one-to-many(或many-to-many)有效,對many-to-one, one-to-one無效。

                 cascade對關係標記都有效。

4.3.2 inverse對集合對象整體起作用,cascade對集合對象中的一個一個元素起作用,如果集合爲空,那麼cascade不會引發關聯操作。

                 比如將集合對象置爲null, school.setStudentSet(null)
                 inverse導致hibernate執行:udpate STUDENT set SCHOOL_ID=null where SCHOOL_ID=?
                 cascade則不會執行對STUDENT表的關聯更新, 因爲集合中沒有元素。

                 再比新增一個school, session.save(school)
                 inverse導致hibernate執行:
                 for( 對(school的每一個student ){
                 udpate STUDENT set SCHOOL_ID=? where STUDENT_ID=? //將學生的school_id改爲新的school的id
                 }
                 cascade導致hibernate執行:
                 for( 對school的每一個student ){
                 session.save(aStudent); //對學生執行save操作
                 }

        extends:如果改變集合中的部分元素(比如新增一個元素),
        inverse: hibernate先判斷哪些元素改變了,對改變的元素執行相應的sql
        cascade: 它總是對集合中的每個元素執行關聯操作。
       (在關聯操作中,hibernate會判斷操作的對象是否改變)

4.3.2 兩個起作用的時機不同:

                 cascade:在對主控方操作時,級聯發生。
                 inverse: 在flush時(commit會自動執行flush),對session中的所有set,hibernate判斷每個set是否有變化,
                 對有變化的set執行相應的sql,執行之前,會有個判斷:if( inverse == true ) return;

                 可以看出cascade在先,inverse在後。

4.3.3 inverse 對set + one-to-many 和 set + many-to-many 起的作用不同。hibernate生成的sql不同。

                 對one-to-many,hibernate對many方的數據庫表執行update語句。
                 對many-to-many, hibernate對關係表執行insert/update/delte語句,注意不是對many方的數據庫表而是關係表。

                 cascase 對set都是一致的,不管one-to-many還是many-to-many。都簡單地把操作傳遞到set中的每個元素。所以它總是更新many
          方的數據庫表。

4.3.4 建議:只對set + many-to-many設置inverse=false,其他的標記不考慮inverse屬性,都設爲inverse=true。

  
                    對cascade,一般對many-to-one,many-to-many,constrained=true的one-to-one 不設置級聯刪除。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章