溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Hibernate中Inverse是什么

發(fā)布時(shí)間:2021-12-06 09:13:25 來(lái)源:億速云 閱讀:145 作者:小新 欄目:編程語(yǔ)言

這篇文章給大家分享的是有關(guān)Hibernate中Inverse是什么的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

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

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

1)Hibernate Inverse中提及的side其實(shí)是指一個(gè)類(lèi)或者表的概念,雙向關(guān)聯(lián)其實(shí)是指雙方都可以取得對(duì)方的應(yīng)用。

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

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

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

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

<?xml version="1.0"?>   <!DOCTYPE Hibernate-mapping PUBLIC   "-//Hibernate/Hibernate Mapping DTD 2.0//EN"   "http://Hibernate.sourceforge.net/Hibernate-mapping-2.0.dtd">   <Hibernate-mapping package="org.Hibernate.auction">   <class name="TestA" table="TestA"   dynamic-update="true" dynamic-insert="true" >     <id name="id" column="id" type="int" unsaved-value="any" >       <generator class="assigned">       </generator>      </id>     <property name="name" type="java.lang.String"       update="true" insert="true" column="name" />     <set name="testBs" table="TestA_TestB" Inverse="false" cascade="all">       <key column="testA"/>       <many-to-many column="testB" class="TestB" />      </set>  </class>   <class name="TestB" table="TestB"   dynamic-update="true" dynamic-insert="true" >     <id name="id" column="id" type="int" unsaved-value="any" >       <generator class="assigned">       </generator>      </id>      <property name="name" type="java.lang.String" update="true"      insert="true" column="name" />      <set name="testAs" table="TestA_TestB" Inverse="true" cascade="all">       <key column="testB"/>       <many-to-many column="testA" class="TestA" />      </set>  </class>   </Hibernate-mapping>

在對(duì)多對(duì)中,因?yàn)橐欢司S護(hù)關(guān)系另一端不維護(hù)關(guān)系的原因,我們必須注意避免在應(yīng)用中用不維護(hù)關(guān)系的類(lèi)建立關(guān)系,因?yàn)檫@樣建立的關(guān)系是不會(huì)在數(shù)據(jù)庫(kù)中存儲(chǔ)的。基于上面的映射文件代碼給出一個(gè)例子:

package org.Hibernate.auction;   import java.util.*;  /**   * @author Administrator   *   * To change the template for this generated type comment go to   * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments   */   public class TestA {   int id;   String name;   Set testBs=new HashSet();   public TestA(){   }   public TestA(int id){      setId(id);   }   public int getId(){      return id;   }   public void setId(int id){      this.id=id;   }   public String getName(){      return name;   }   public void setName(String name){      this.name=name;   }   public Set getTestBs(){      return testBs;   }   public void setTestBs(Set s){      testBs=s;   }   public void addTestB(TestB tb){      testBs.add(tb);   }public static void main(String[] args) {   }   }  public class TestB {  int id;   String name;   Set testAs=new HashSet();   public TestB(){   }   public TestB(int id){      setId(id);   }   public int getId(){      return id;   }   public void setId(int id){      this.id=id;   }   public String getName(){      return name;   }   public void setName(String name){      this.name=name;   }   public Set getTestAs(){      return testAs;   }   public void setTestAs(Set s){      testAs=s;   }   public void addTestA(TestA ta){      testAs.add(ta);   }   public static void main(String[] args) {   }   }

測(cè)試代碼:

public void doTest() throws Exception{      TestA a1=new TestA(1);      TestA a2=new TestA(2);      TestA a3=new TestA(3);      TestB b1=new TestB(1);      TestB b2=new TestB(2);      TestB b3=new TestB(3);      a1.addTestB(b1);      a1.addTestB(b2);      a1.addTestB(b3);      b2.addTestA(a1);      b2.addTestA(a2);      Session s = factory.openSession();      s = factory.openSession();      Session session = factory.openSession();   session.save(a1);   session.flush();   session.close();  }

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

testa              testb

1                  1

1                  2

1                  3

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

/*   * Created on 2004-7-25   *   * To change the template for this generated file go to   * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments   */   package org.Hibernate.auction;   import java.util.*;  /**   * @author Administrator   *   * To change the template for this generated type comment go to   * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments   */   public class TestB {  int id;   String name;   Set testAs=new HashSet();   public TestB(){   }   public TestB(int id){      setId(id);   }   public int getId(){      return id;   }   public void setId(int id){      this.id=id;   }   public String getName(){      return name;   }   public void setName(String name){      this.name=name;   }   public Set getTestAs(){      return testAs;   }   public void setTestAs(Set s){      testAs=s;   }   public void addTestA(TestA ta){      testAs.add(ta);      ta.addTestB(this);   }   public static void main(String[] args) {   }   }

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

testa          testb

1               2

1               3

1               1

2               2

測(cè)試通過(guò)。

感謝各位的閱讀!關(guān)于“Hibernate中Inverse是什么”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI