<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 64,  comments - 9,  trackbacks - 0

    通過Hibernate Inverse的設(shè)置來決定是由誰來維護表和表之間的關(guān)系。最近有朋友問我Hibernate關(guān)于多對多關(guān)于刪除中間表數(shù)據(jù)的問題,關(guān)鍵是Inverse的設(shè)置,下面引用網(wǎng)友的一篇文章。

    Inverse是Hibernate雙向關(guān)系中的基本概念,當然對于多數(shù)實體,我們并不需要雙向關(guān)聯(lián),更多的可能會選擇單向關(guān)聯(lián),況且我們大多數(shù)人 一般采用一對多關(guān)系,而一對多雙向關(guān)聯(lián)的另一端:多對一的Inverse屬性是不存在,其實它默認就是Inverse=false.從而防止了在一對多端 胡亂設(shè)置Inverse也不至于出錯。但是Inverse設(shè)置不當確實會帶來很大的性能影響,這點是我們必須關(guān)注的。

    這篇文章已經(jīng)詳細分析了Hibernate Inverse設(shè)置不當帶來的影響:http://www.Hibernate.org/155.html,看了這篇文章,還是很有必要再寫下一些總結(jié)的:

    1)Hibernate Inverse中提及的side其實是指一個類或者表的概念,雙向關(guān)聯(lián)其實是指雙方都可以取得對方的應用。

    2)維護關(guān)系這個名詞還是稍顯模糊或者晦澀。我們一般說A類或者A表(這里的表的是指多對多的連接表)有責任維護關(guān)系,其實這里的意思是說,我在應 用在更新,創(chuàng)建,刪除(讀就不用說了,雙向引用正是為了方便讀而出現(xiàn))A類或者A表時,此時創(chuàng)建的SQL語句必須有責任保證關(guān)系的正確修改。

    3)Inverse=false的side(side其實是指Inverse=false所位于的class元素)端有責任維護關(guān)系,而Inverse=true端無須維護這些關(guān)系。

    4)我們說Hibernate Inverse設(shè)立不當會導致性能低下,其實是說Inverse設(shè)立不當,會產(chǎn)生多余重復的SQL語句甚至致使JDBC exception的throw。這是我們在建立實體類關(guān)系時必須需要關(guān)注的地方。一般來說,Inverse=true是推薦使用,雙向關(guān)聯(lián)中雙方都設(shè)置 Inverse=false的話,必會導致雙方都重復更新同一個關(guān)系。但是如果雙方都設(shè)立Inverse=true的話,雙方都不維護關(guān)系的更新,這也是 不行的,好在一對多中的一端:many-to-one默認是Inverse=false,避免了這種錯誤的產(chǎn)生。但是多對多就沒有這個默認設(shè)置了,所以很 多人經(jīng)常在多對多的兩端都使用Inverse=true,結(jié)果導致連接表的數(shù)據(jù)根本沒有記錄,就是因為他們雙分都沒有責任維護關(guān)系。所以說,雙向關(guān)聯(lián)中最 好的設(shè)置是一端為Inverse=true,一端為Inverse=false。一般Inverse=false會放在多的一端,那么有人提問了, many-to-many兩邊都是多的,Inverse到底放在哪兒?其實Hibernate建立多對多關(guān)系也是將他們分離成兩個一對多關(guān)系,中間連接一 個連接表。所以通用存在一對多的關(guān)系,也可以這樣說:一對多是多對多的基本組成部分。

    看下面的多對多的定義大家更會清楚”多對多“與“一對多”的關(guān)系:其中我們注意<many-to-many />標簽的特點就知道,它是定義了一個多對多關(guān)系,而不是<one-to-many/>。

    1. <?xml version="1.0"?>   
    2. <!DOCTYPE Hibernate-mapping PUBLIC   
    3. "-//Hibernate/Hibernate Mapping DTD 2.0//EN"   
    4. "http://Hibernate.sourceforge.net/Hibernate-mapping-2.0.dtd">   
    5. <Hibernate-mapping package="org.Hibernate.auction">   
    6. <class name="TestA" table="TestA"   
    7. dynamic-update="true" dynamic-insert="true" >  
    8.    <id name="id" column="id" type="int" unsaved-value="any" >   
    9.     <generator class="assigned">   
    10.     </generator>   
    11.    </id>  
    12.    <property name="name" type="java.lang.String"   
    13.     update="true" insert="true" column="name" />  
    14.    <set name="testBs" table="TestA_TestB" Inverse="false" cascade="all">   
    15.     <key column="testA"/>   
    16.     <many-to-many column="testB" class="TestB" />   
    17.    </set>  
    18. </class>   
    19. <class name="TestB" table="TestB"   
    20. dynamic-update="true" dynamic-insert="true" >  
    21.    <id name="id" column="id" type="int" unsaved-value="any" >   
    22.     <generator class="assigned">   
    23.     </generator>   
    24.    </id>  
    25.  
    26.    <property name="name" type="java.lang.String" update="true"   
    27.    insert="true" column="name" />  
    28.  
    29.    <set name="testAs" table="TestA_TestB" Inverse="true" cascade="all">   
    30.     <key column="testB"/>   
    31.     <many-to-many column="testA" class="TestA" />   
    32.    </set>  
    33. </class>   
    34. </Hibernate-mapping> 

    在對多對中,因為一端維護關(guān)系另一端不維護關(guān)系的原因,我們必須注意避免在應用中用不維護關(guān)系的類建立關(guān)系,因為這樣建立的關(guān)系是不會在數(shù)據(jù)庫中存儲的。基于上面的映射文件代碼給出一個例子:

    1. package org.Hibernate.auction;   
    2. import java.util.*;  
    3. /**   
    4. * @author Administrator   
    5.  
    6. * To change the template for this generated type comment go to   
    7. * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments   
    8. */   
    9. public class TestA {   
    10. int id;   
    11. String name;   
    12. Set testBs=new HashSet();   
    13. public TestA(){   
    14. }   
    15. public TestA(int id){   
    16.    setId(id);   
    17. }   
    18. public int getId(){   
    19.    return id;   
    20. }   
    21. public void setId(int id){   
    22.    this.id=id;   
    23. }   
    24. public String getName(){   
    25.    return name;   
    26. }   
    27. public void setName(String name){   
    28.    this.name=name;   
    29. }   
    30. public Set getTestBs(){   
    31.    return testBs;   
    32. }   
    33. public void setTestBs(Set s){   
    34.    testBs=s;   
    35. }   
    36. public void addTestB(TestB tb){   
    37.    testBs.add(tb);   
    38. }public static void main(String[] args) {   
    39. }   
    40. }  
    41. public class TestB {  
    42. int id;   
    43. String name;   
    44. Set testAs=new HashSet();   
    45. public TestB(){   
    46. }   
    47. public TestB(int id){   
    48.    setId(id);   
    49. }   
    50. public int getId(){   
    51.    return id;   
    52. }   
    53. public void setId(int id){   
    54.    this.id=id;   
    55. }   
    56. public String getName(){   
    57.    return name;   
    58. }   
    59. public void setName(String name){   
    60.    this.name=name;   
    61. }   
    62. public Set getTestAs(){   
    63.    return testAs;   
    64. }   
    65. public void setTestAs(Set s){   
    66.    testAs=s;   
    67. }   
    68. public void addTestA(TestA ta){   
    69.    testAs.add(ta);   
    70. }   
    71. public static void main(String[] args) {   
    72. }   

    測試代碼:

    1. public void doTest() throws Exception{   
    2.    TestA a1=new TestA(1);   
    3.    TestA a2=new TestA(2);   
    4.    TestA a3=new TestA(3);   
    5.    TestB b1=new TestB(1);   
    6.    TestB b2=new TestB(2);   
    7.    TestB b3=new TestB(3);   
    8.    a1.addTestB(b1);   
    9.    a1.addTestB(b2);   
    10.    a1.addTestB(b3);   
    11.    b2.addTestA(a1);   
    12.    b2.addTestA(a2);   
    13.    Session s = factory.openSession();   
    14.    s = factory.openSession();   
    15.    Session session = factory.openSession();   
    16. session.save(a1);   
    17. session.flush();   
    18. session.close();  

    測試后連接表的數(shù)據(jù)為:

    testa              testb

    1                  1

    1                  2

    1                  3

    根據(jù)Inverse規(guī)則,對這些代碼:b2.addTestA(a1);   b2.addTestA(a2); 建立的關(guān)系,數(shù)據(jù)庫并沒有存儲下來,因為TestB沒有責任維護這些關(guān)系,所以產(chǎn)生的sql語句自然不會有針對Testa_testB表的操作了。假設(shè)應 用中真的需要這些方法,那么我們可以修改TestB的方法,讓他們注意在維護端類中執(zhí)行相應的操作以使得關(guān)系能夠在數(shù)據(jù)庫中保存下來,更改TestB如 下:

    1. /*   
    2. * Created on 2004-7-25   
    3.  
    4. * To change the template for this generated file go to   
    5. * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments   
    6. */   
    7. package org.Hibernate.auction;   
    8. import java.util.*;  
    9. /**   
    10. * @author Administrator   
    11.  
    12. * To change the template for this generated type comment go to   
    13. * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments   
    14. */   
    15. public class TestB {  
    16. int id;   
    17. String name;   
    18. Set testAs=new HashSet();   
    19. public TestB(){   
    20. }   
    21. public TestB(int id){   
    22.    setId(id);   
    23. }   
    24. public int getId(){   
    25.    return id;   
    26. }   
    27. public void setId(int id){   
    28.    this.id=id;   
    29. }   
    30. public String getName(){   
    31.    return name;   
    32. }   
    33. public void setName(String name){   
    34.    this.name=name;   
    35. }   
    36. public Set getTestAs(){   
    37.    return testAs;   
    38. }   
    39. public void setTestAs(Set s){   
    40.    testAs=s;   
    41. }   
    42. public void addTestA(TestA ta){   
    43.    testAs.add(ta);   
    44.    ta.addTestB(this);   
    45. }   
    46. public static void main(String[] args) {   
    47. }   
    48. }  

    那么測試執(zhí)行后連接表的數(shù)據(jù)為:

    testa          testb

    1               2

    1               3

    1               1

    2               2

    測試通過。

    posted on 2009-07-30 12:04 super_nini 閱讀(1462) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
     
    <2009年7月>
    2829301234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    常用鏈接

    留言簿

    隨筆檔案

    文章檔案

    相冊

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲中文字幕无码不卡电影| 久久久久久久久免费看无码| 亚洲第一页在线观看| 免费一级做a爰片久久毛片潮喷| 亚洲国产成人综合精品| 亚洲成Av人片乱码色午夜| 四虎影视精品永久免费网站| 在线看免费观看AV深夜影院| h片在线播放免费高清| 亚洲日本在线电影| 亚洲伊人久久大香线蕉苏妲己| 亚洲一区二区免费视频| 亚洲欧洲免费无码| 亚洲欧洲无码AV不卡在线| 精品亚洲成A人在线观看青青| 久久亚洲av无码精品浪潮| 免费无码作爱视频| 免费一级做a爰片久久毛片潮| 亚洲国产精品国自产拍AV| 免费a级毛片视频| 亚洲午夜精品一级在线播放放| 嫩草在线视频www免费观看| 一级做a爰片久久免费| 国产亚洲精品国产福利在线观看| 亚洲精品无码mv在线观看网站 | 国产亚洲?V无码?V男人的天堂 | 国内精品免费久久影院| 国产在亚洲线视频观看| 一级特黄色毛片免费看| 国产精品免费无遮挡无码永久视频 | 国产高清免费观看| 最近中文字幕免费mv视频8| 曰批全过程免费视频网址| 免费91最新地址永久入口| 中文字幕免费在线看线人动作大片 | 免费a级毛片无码av| 亚洲级αV无码毛片久久精品| 中文国产成人精品久久亚洲精品AⅤ无码精品| 精品免费国产一区二区三区 | 亚洲四虎永久在线播放| 亚洲成av人片在线观看无码不卡|