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

創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比墊江網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式墊江網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋墊江地區(qū)。費(fèi)用合理售后完善,十載實(shí)體公司更值得信賴。
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ì)帶來很大的性能影響,這點(diǎn)是我們必須關(guān)注的。
這篇文章已經(jīng)詳細(xì)分析了Hibernate Inverse設(shè)置不當(dāng)帶來的影響:http://www.Hibernate.org/155.html,看了這篇文章,還是很有必要再寫下一些總結(jié)的:
1)Hibernate Inverse中提及的side其實(shí)是指一個(gè)類或者表的概念,雙向關(guān)聯(lián)其實(shí)是指雙方都可以取得對(duì)方的應(yīng)用。
2)維護(hù)關(guān)系這個(gè)名詞還是稍顯模糊或者晦澀。我們一般說A類或者A表(這里的表的是指多對(duì)多的連接表)有責(zé)任維護(hù)關(guān)系,其實(shí)這里的意思是說,我在應(yīng) 用在更新,創(chuàng)建,刪除(讀就不用說了,雙向引用正是為了方便讀而出現(xiàn))A類或者A表時(shí),此時(shí)創(chuàng)建的SQL語句必須有責(zé)任保證關(guān)系的正確修改。
3)Inverse=false的side(side其實(shí)是指Inverse=false所位于的class元素)端有責(zé)任維護(hù)關(guān)系,而Inverse=true端無須維護(hù)這些關(guān)系。
4)我們說Hibernate Inverse設(shè)立不當(dāng)會(huì)導(dǎo)致性能低下,其實(shí)是說Inverse設(shè)立不當(dāng),會(huì)產(chǎn)生多余重復(fù)的SQL語句甚至致使JDBC exception的throw。這是我們?cè)诮?shí)體類關(guān)系時(shí)必須需要關(guān)注的地方。一般來說,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ì)多就沒有這個(gè)默認(rèn)設(shè)置了,所以很 多人經(jīng)常在多對(duì)多的兩端都使用Inverse=true,結(jié)果導(dǎo)致連接表的數(shù)據(jù)根本沒有記錄,就是因?yàn)樗麄冸p分都沒有責(zé)任維護(hù)關(guān)系。所以說,雙向關(guān)聯(lián)中***的設(shè)置是一端為Inverse=true,一端為Inverse=false。一般Inverse=false會(huì)放在多的一端,那么有人提問了, many-to-many兩邊都是多的,Inverse到底放在哪兒?其實(shí)Hibernate建立多對(duì)多關(guān)系也是將他們分離成兩個(gè)一對(duì)多關(guān)系,中間連接一 個(gè)連接表。所以通用存在一對(duì)多的關(guān)系,也可以這樣說:一對(duì)多是多對(duì)多的基本組成部分。
看下面的多對(duì)多的定義大家更會(huì)清楚”多對(duì)多“與“一對(duì)多”的關(guān)系:其中我們注意
- "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
- "http://Hibernate.sourceforge.net/Hibernate-mapping-2.0.dtd">
- dynamic-update="true" dynamic-insert="true" >
- update="true" insert="true" column="name" />
- dynamic-update="true" dynamic-insert="true" >
- insert="true" column="name" />
在對(duì)多對(duì)中,因?yàn)橐欢司S護(hù)關(guān)系另一端不維護(hù)關(guān)系的原因,我們必須注意避免在應(yīng)用中用不維護(hù)關(guān)系的類建立關(guān)系,因?yàn)檫@樣建立的關(guān)系是不會(huì)在數(shù)據(jù)庫中存儲(chǔ)的?;谏厦娴挠成湮募a給出一個(gè)例子:
- 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();
- }
測試后連接表的數(shù)據(jù)為:
testa testb
1 1
1 2
1 3
根據(jù)Inverse規(guī)則,對(duì)這些代碼:b2.addTestA(a1); b2.addTestA(a2); 建立的關(guān)系,數(shù)據(jù)庫并沒有存儲(chǔ)下來,因?yàn)門estB沒有責(zé)任維護(hù)這些關(guān)系,所以產(chǎn)生的sql語句自然不會(huì)有針對(duì)Testa_testB表的操作了。假設(shè)應(yīng) 用中真的需要這些方法,那么我們可以修改TestB的方法,讓他們注意在維護(hù)端類中執(zhí)行相應(yīng)的操作以使得關(guān)系能夠在數(shù)據(jù)庫中保存下來,更改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) {
- }
- }
那么測試執(zhí)行后連接表的數(shù)據(jù)為:
testa testb
1 2
1 3
1 1
2 2
測試通過。
【編輯推薦】
- 強(qiáng)人Hibernate文檔筆記(上)
- 強(qiáng)人Hibernate文檔筆記(中)
- 強(qiáng)人Hibernate文檔筆記(下)
- Hibernate一對(duì)多關(guān)系的處理
- Hibernate的性能優(yōu)化
文章題目:正確理解HibernateInverse
網(wǎng)站路徑:http://fisionsoft.com.cn/article/dhdscse.html


咨詢
建站咨詢
