总结:直观来说所有双向关联须有有一段设置为inverse。在一对多的关联中它必须代表多(many)的那端。而在多对多(many-to-many)关联中,可以选取任意一端,因为两端之间并没有差别。

以下为转贴:

通过Hibernate Inverse的设置来决定是由谁来维护表和表之间的关系。最近有朋友问我Hibernate关于多对多关于删除中间表数据的问题,关键是Inverse的设置,下面引用网友的一篇文章。

Inverse是Hibernate双向关系中的基本概念,当然对于多数实体,我们并不需要双向关联,更多的可能会选择单向关联,况且我们大多数人 一般采用一对多关系,而一对多双向关联的另一端:多对一的Inverse属性是不存在,其实它默认就是Inverse=false.从而防止了在一对多端 胡乱设置Inverse也不至于出错。但是Inverse设置不当确实会带来很大的性能影响,这点是我们必须关注的。

关于inverse和cascade的区别

cascade:设置级联

sava-update:级联保存、更新

delete:级联删除

none:不级联,默认值

all:级联保存、更新、删除

inverse:在映射一对多关系时,一般将该属性设置为true,表示表间的关联关系由一方设置,减少update语句,提高性能

这篇文章已经详细分析了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建立多对多关系也是将他们分离成两个一对多关系,中间连接一 个连接表。所以通用存在一对多的关系,也可以这样说:一对多是多对多的基本组成部分。

看下面的多对多的定义大家更会清楚”多对多“与“一对多”的关系:其中我们注意标签的特点就知道,它是定义了一个多对多关系,而不是。

Xml代码

Hibernate-mapping PUBLIC   "-//Hibernate/Hibernate Mapping DTD 2.0//EN"   "http://Hibernate.sourceforge.net/Hibernate-mapping-2.0.dtd">

dynamic-insert="true">

insert="true"column="name"/>

dynamic-insert="true">

insert="true"column="name"/>

<?xml version="1.0" encoding="UTF-8"?>  "-//Hibernate/Hibernate Mapping DTD 2.0//EN"

"http://Hibernate.sourceforge.net/Hibernate-mapping-2.0.dtd">

在对多对中,因为一端维护关系另一端不维护关系的原因,我们必须注意避免在应用中用不维护关系的类建立关系,因为这样建立的关系是不会在数据库中存储的。基于上面的映射文件代码给出一个例子:

Java代码

packageorg.Hibernate.auction;

importjava.util.*;

/**

* * @author Administrator * * To change the template for this generated type

* comment go to * Window>Preferences>Java>Code Generation>Code and

* Comments

*/

publicclassTestA {

intid;

String name;

Set testBs = newHashSet();

publicTestA() {

}

publicTestA(intid) {

setId(id);

}

publicintgetId() {

returnid;

}

publicvoidsetId(intid) {

this.id = id;

}

publicString getName() {

returnname;

}

publicvoidsetName(String name) {

this.name = name;

}

publicSet getTestBs() {

returntestBs;

}

publicvoidsetTestBs(Set s) {

testBs = s;

}

publicvoidaddTestB(TestB tb) {

testBs.add(tb);

}

publicstaticvoidmain(String[] args) {

}

}

publicclassTestB {

intid;

String name;

Set testAs = newHashSet();

publicTestB() {

}

publicTestB(intid) {

setId(id);

}

publicintgetId() {

returnid;

}

publicvoidsetId(intid) {

this.id = id;

}

publicString getName() {

returnname;

}

publicvoidsetName(String name) {

this.name = name;

}

publicSet getTestAs() {

returntestAs;

}

publicvoidsetTestAs(Set s) {

testAs = s;

}

publicvoidaddTestA(TestA ta) {

testAs.add(ta);

}

publicstaticvoidmain(String[] args) {

}

}

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) {}}

测试代码:

Java代码

publicvoiddoTest()throwsException {

TestA a1 = newTestA(1);

TestA a2 = newTestA(2);

TestA a3 = newTestA(3);

TestB b1 = newTestB(1);

TestB b2 = newTestB(2);

TestB b3 = newTestB(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();

}

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如 下:

Java代码

/*   * Created on 2004-7-25

*   * To change the template for this generated file go to   * Window>Preferences>Java>Code Generation>Code and Comments   */packageorg.Hibernate.auction;

importjava.util.*;

/**

* * @author Administrator * * To change the template for this generated type

* comment go to * Window>Preferences>Java>Code Generation>Code and

* Comments

*/

publicclassTestB {

intid;

String name;

Set testAs = newHashSet();

publicTestB() {

}

publicTestB(intid) {

setId(id);

}

publicintgetId() {

returnid;

}

publicvoidsetId(intid) {

this.id = id;

}

publicString getName() {

returnname;

}

publicvoidsetName(String name) {

this.name = name;

}

publicSet getTestAs() {

returntestAs;

}

publicvoidsetTestAs(Set s) {

testAs = s;

}

publicvoidaddTestA(TestA ta) {

testAs.add(ta);

ta.addTestB(this);

}

publicstaticvoidmain(String[] args) {

}

}

/* * 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

测试通过。

inverse java_Hibernate中的inverse的用法相关推荐

  1. one-many和many-one的关系中的inverse的详解

    在one-many和many-one的关系中的inverse的详解. 1.现在假设有两个类Customer与Order,一个Customer可以有多个Order 2. 如果在Customer.hbm. ...

  2. PHP中魔术方法的用法

    PHP中魔术方法的用法 /** PHP把所有以__(两个下划线)开头的类方法当成魔术方法.所以你定义自己的类方法时,不要以 __为前缀. * */// __toString.__set.__get__ ...

  3. 简单介绍SQLserver中的declare变量用法

    这篇文章主要介绍了SQLserver中的declare变量用法,sql中declare是声明的意思,就是声明变量的,这个一般是用在函数和存储过程中的.感兴趣的可以来了解一下 平时写SQL查询.存储过程 ...

  4. python的继承用法_【后端开发】python中继承有什么用法?python继承的用法详解

    本篇文章给大家带来的内容是关于python中继承有什么用法?python继承的用法详解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 面向对象三大特征 1.封装:根据职责将属性和方法 ...

  5. 关于sql中case when的用法

    Oracle CASE WHEN 用法介绍 1. CASE WHEN 表达式有两种形式 --简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ...

  6. 【node】express中mysql的基本用法、连接池的使用、事务的回滚

    [node]express中mysql的基本用法.连接池的使用 安装mysql包 mysql的配置信息 mysql基本操作 查询mysql并渲染数据 mysql插入操作 首先在html页面写上< ...

  7. git 只merge部分_[Skill]俩小时掌握多人开发中git的主要用法

    前言 几个月前看完了git文档,但是在实际开发中对很多git命令的具体影响仍有疑惑,比方说pull.fetch和rebase三个命令和检出位置拎不清. Git - Book​git-scm.com 安 ...

  8. python的for语句用法_python中list循环语句用法实例

    本文实例讲述了python中list循环语句用法.分享给大家供大家参考.具体用法分析如下: Python 的强大特性之一就是其对 list 的解析,它提供一种紧凑的方法,可以通过对 list 中的每个 ...

  9. wince中的hook(钩子)用法

    wince中的hook(钩子)用法 Hook(钩子)是一种在消息到达目标窗口前进行截获的技术.使用钩子主要使用以下三个函数SetWindowsHookEx:创建钩子 CallNextHookEx:将消 ...

最新文章

  1. linux图形界面编程基本知识
  2. python 怎么安装电脑摄像头模块_Python模块及安装
  3. 史上最硬核文科生,擅长解决数学难题,却视考试成为终生噩梦
  4. js进阶正则表达式14验证邮编(input的pattern属性)(正则表达式加起^始$)
  5. Maven 入门——认识Maven结构
  6. 测试金士顿固态硬盘软件,金士顿固态硬盘管理工具(Kingston SSD Manager)
  7. 《货币金融学》期末复习题
  8. SpringBoot微服务项目打包流程
  9. 用python代码实现一个简单的FSA(有限状态自动机)
  10. java本地外地号码,将JavaAnpr本地化为本地牌照
  11. Visual C++6.0画三维立体图形
  12. 华硕服务器主板引导设置,装系统时的引导设置_华硕 ROG Rampage VI Apex_主板评测-中关村在线...
  13. 5.深度解密五:网站被百度搜索引擎降权的原因及百度算法汇总
  14. 微信直播小程序端集成源代码
  15. android 设置单边框,Android设置单边圆角边框
  16. 基于FPGA的UART全双工数据控制器
  17. intellij背景护眼色调节
  18. iftop命令命令详解
  19. 有效解决solidworks无法获得下列许可solidworks standard。使用此许可文件不支持此版本(-21.126.0)
  20. 下载视频网站flv文件的两种方法(080526添加新方法)

热门文章

  1. 阿里携人工智能新进展亮相法国Viva Tech峰会
  2. python程序设计实用教程_《Python程序设计实用教程》【摘要 书评 试读】- 京东图书...
  3. 搞流量的小道道(扶摇生财思维)
  4. 服务器僵尸猪人刷怪塔怎么制作,我的世界僵尸猪人刷怪塔制作思路 猪人塔介绍...
  5. 315诚信季:家电维修清洗的套路你都懂吗?
  6. 爬虫第二弹 图片解析
  7. 做生意只做自己熟悉的领域,挣钱只挣自己认知以内的钱
  8. 2021年想做生意赚钱,一定要学会生意必备6个APP
  9. 数据从HDFS文件迁移到Hive
  10. border英文缩写_CSS编码规范