您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關Hibernate中Inverse是什么的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
Inverse是Hibernate雙向關系中的基本概念,當然對于多數實體,我們并不需要雙向關聯,更多的可能會選擇單向關聯,況且我們大多數人 一般采用一對多關系,而一對多雙向關聯的另一端:多對一的Inverse屬性是不存在,其實它默認就是Inverse=false.從而防止了在一對多端 胡亂設置Inverse也不至于出錯。但是Inverse設置不當確實會帶來很大的性能影響,這點是我們必須關注的。
這篇文章已經詳細分析了Hibernate Inverse設置不當帶來的影響:http://www.Hibernate.org/155.html,看了這篇文章,還是很有必要再寫下一些總結的:
1)Hibernate Inverse中提及的side其實是指一個類或者表的概念,雙向關聯其實是指雙方都可以取得對方的應用。
2)維護關系這個名詞還是稍顯模糊或者晦澀。我們一般說A類或者A表(這里的表的是指多對多的連接表)有責任維護關系,其實這里的意思是說,我在應 用在更新,創建,刪除(讀就不用說了,雙向引用正是為了方便讀而出現)A類或者A表時,此時創建的SQL語句必須有責任保證關系的正確修改。
3)Inverse=false的side(side其實是指Inverse=false所位于的class元素)端有責任維護關系,而Inverse=true端無須維護這些關系。
4)我們說Hibernate Inverse設立不當會導致性能低下,其實是說Inverse設立不當,會產生多余重復的SQL語句甚至致使JDBC exception的throw。這是我們在建立實體類關系時必須需要關注的地方。一般來說,Inverse=true是推薦使用,雙向關聯中雙方都設置 Inverse=false的話,必會導致雙方都重復更新同一個關系。但是如果雙方都設立Inverse=true的話,雙方都不維護關系的更新,這也是 不行的,好在一對多中的一端:many-to-one默認是Inverse=false,避免了這種錯誤的產生。但是多對多就沒有這個默認設置了,所以很 多人經常在多對多的兩端都使用Inverse=true,結果導致連接表的數據根本沒有記錄,就是因為他們雙分都沒有責任維護關系。所以說,雙向關聯中***的設置是一端為Inverse=true,一端為Inverse=false。一般Inverse=false會放在多的一端,那么有人提問了, many-to-many兩邊都是多的,Inverse到底放在哪兒?其實Hibernate建立多對多關系也是將他們分離成兩個一對多關系,中間連接一 個連接表。所以通用存在一對多的關系,也可以這樣說:一對多是多對多的基本組成部分。
看下面的多對多的定義大家更會清楚”多對多“與“一對多”的關系:其中我們注意<many-to-many />標簽的特點就知道,它是定義了一個多對多關系,而不是<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>
在對多對中,因為一端維護關系另一端不維護關系的原因,我們必須注意避免在應用中用不維護關系的類建立關系,因為這樣建立的關系是不會在數據庫中存儲的。基于上面的映射文件代碼給出一個例子:
package org.Hibernate.auction; import java.util.*; /** * @author Administrator * * To change the template for this generated type comment go to * Window>Preferences>Java>Code Generation>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) { } }
測試代碼:
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(); }
測試后連接表的數據為:
testa testb
1 1
1 2
1 3
根據Inverse規則,對這些代碼:b2.addTestA(a1); b2.addTestA(a2); 建立的關系,數據庫并沒有存儲下來,因為TestB沒有責任維護這些關系,所以產生的sql語句自然不會有針對Testa_testB表的操作了。假設應 用中真的需要這些方法,那么我們可以修改TestB的方法,讓他們注意在維護端類中執行相應的操作以使得關系能夠在數據庫中保存下來,更改TestB如 下:
/* * Created on 2004-7-25 * * To change the template for this generated file go to * Window>Preferences>Java>Code Generation>Code and Comments */ package org.Hibernate.auction; import java.util.*; /** * @author Administrator * * To change the template for this generated type comment go to * Window>Preferences>Java>Code Generation>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) { } }
那么測試執行后連接表的數據為:
testa testb
1 2
1 3
1 1
2 2
測試通過。
感謝各位的閱讀!關于“Hibernate中Inverse是什么”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。