在hibernate中是通过inverse的设置来决定是有谁来维护表和表之间的关系的
最近有朋友问我hibernate关于多对多关于删除中间表数据的问题,关键是inverse的设置.下面引用网友的一篇文章
Inverse是hibernate双向关系中的基本概念,当然对于多数实体,我们并不需要双向关联,更多的可能会选择单向关联,况且我们大多数人一般采用一对多关系,而一对多双向关联的另一端:多对一的inverse属性是不存在,其实它默认就是inverse=false.从而防止了在一对多端胡乱设置inverse也不至于出错。但是inverse设置不当确实会带来很大的性能影响,这点是我们必须关注的。
这篇文章已经详细分析了inverse设置不当带来的影响:
http://www.hibernate.org/155.html
看了这篇文章,还是很有必要再写下一些总结的:
1)inverse中提及的side其实是指一个类或者表的概念,双向关联其实是指双方都可以取得对方的应用。
2)维护关系这个名词还是稍显模糊或者晦涩。我们一般说A类或者A表(这里的表的是指多对多的连接表)有责任维护关系,其实这里的意思是说,我在应用在更新,创建,删除(读就不用说了,双向引用正是为了方便读而出现)A类或者A表时,此时创建的SQL语句必须有责任保证关系的正确修改。
3)inverse=false的side(side其实是指inverse=false所位于的class元素)端有责任维护关系,而inverse=true端无须维护这些关系。
4)我们说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
测试通过。
分享到:
相关推荐
这是对spring_hibernate_struts2的理解,可以在面试中简要的抓住重点进行陈述。
高级Hibernate4开发技术:ORM思想,hibernate介绍,hibernate.cfg.xml配置,hbm.xml映射文件详解,主键生成策略使用,PO对象状态及状态的转换分析、一级缓存,Hibernate数据检索技术,Hibernate高级映射技术,...
【标题】"Hibernate入门理解" Hibernate 是一个开源的Java对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以使用面向对象的方式处理数据。这篇博客文章将引导初学者进入Hibernate的世界,理解其核心...
这个压缩包包含了丰富的Hibernate学习资源,旨在帮助开发者深入理解和熟练掌握这一强大的工具。 1. **对象关系映射(ORM)基础**: Hibernate 提供了一种将Java对象模型与关系数据库之间的映射机制,使得开发者...
标题"Hibernate 中文api 等学习资料"暗示了这是一组针对Hibernate ORM框架的中文学习资源,包括API文档和其他指南,旨在帮助用户更好地理解和使用Hibernate。 描述中的"hibernate orm框架api中文文档,学习资料,...
Hibernate入门讲义,理解ORM概念Hibernate入门讲义,理解ORM概念Hibernate入门讲义,理解ORM概念Hibernate入门讲义,理解ORM概念Hibernate入门讲义,理解ORM概念Hibernate入门讲义,理解ORM概念
而"使用帮助手册"则可能包括用户指南、API文档和示例代码,它们为开发者提供了详尽的指引,帮助理解Hibernate的工作原理、配置方法以及如何进行数据库交互。 【标签】"Hibernate"表明这个压缩包主要涉及的是...
KingbaseV8的方言文件可以帮助Hibernate理解和处理KingbaseV8特有的SQL语法和特性。 总结来说,这个压缩包包含了不同版本的Hibernate核心库以及可能的KingbaseV8 JDBC驱动和方言实现,这些组件使得开发者能够利用...
Hibernate3 是一个非常重要的Java持久化框架,它简化了数据库操作,使得开发人员可以更加专注于业务逻辑而不是...理解并熟练使用这些概念,可以帮助Java开发者更高效地进行数据库操作,提升应用程序的开发速度和质量。
《深入理解Hibernate配置与映射:hibernate-configuration-3.0.dtd与hibernate-mapping-3.0.dtd解析》 在Java世界里,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。而`hibernate-...
### 关于《Beginning Hibernate: For Hibernate 5》的知识点总结 #### Hibernate 5 概述 - **定义**: Hibernate 是一款流行的开源对象关系映射(ORM)框架,它简化了数据库与 Java 对象之间的交互过程。 - **版本**...
【Hibernate入门案例源码】是针对初学者设计的一份教程,旨在帮助理解并掌握Java持久化框架Hibernate的基础应用。Hibernate是一个强大的ORM(对象关系映射)框架,它简化了数据库与Java对象之间的交互,使开发者可以...
在Hibernate 3.2版本中,开发者们能够更深入地理解其内部机制,从而提高开发效率和应用性能。本篇文章将详细解析Hibernate 3.2的核心功能和源代码结构。 一、Hibernate概览 Hibernate是Java社区中的明星项目,它...
### Hibernate实战知识点解析 #### 一、书籍简介与评价概览 《Hibernate实战》是一部备受赞誉的关于Hibernate框架的专业书籍,被广泛认为是最权威的Hibernate著作之一。该书由Hibernate项目的核心开发者撰写,因此...
《Hibernate 3.6 中文 CHM》是一个针对Hibernate 3.6版本的详细使用指南,旨在帮助开发者理解和掌握这个强大的对象关系映射(ORM)框架。Hibernate是Java开发中的一个重要工具,它允许程序员以面向对象的方式处理...
首先,让我们理解Hibernate的基础知识。Hibernate是一种开源的ORM框架,它通过映射Java类到数据库表,使得开发者可以使用面向对象的方式来操作数据库。这消除了SQL的直接编写,降低了数据库访问的复杂性。Hibernate...
方言定义了如何将Hibernate的SQL语句转换为特定数据库所理解的SQL,包括列类型、约束、SQL语法等。例如,达梦Hibernate方言会包含对达梦特有的数据类型、函数和存储过程的适配。 对于“达梦Hibernate方言2.0至4.0”...
Hibernate.jar包,Hibernate可以应用在任何使用JDBC的场合,包含 hibernate-commons-annotations-4.0.1.Final.jar hibernate-core-4.1.12.Final.jar hibernate-ehcache-4.1.12.Final.jar hibernate-entitymanager-...
Hibernate 是一个开源的对象关系映射(ORM)框架,它允许...理解和熟练使用Hibernate配置、异常处理、HQL查询以及IDE集成是每个Java开发者必备的技能。通过上述步骤,你可以更好地了解和应用Hibernate进行数据库操作。