`
myqhit
  • 浏览: 64618 次
社区版块
存档分类
最新评论

inverse

    博客分类:
  • java
阅读更多

前不久在搭建系统框架的时候遇到one-many与many-one的关系中一个比较麻烦的问题,就是inverse的设置,看到在这里也有许多人提出这个问题,也有许多解决方法,自己总结总结以
后作为资料库吧。
1.现在假设有两个类Customer与Order,一个Customer可以有多个Order


2.如果在Customer.hbm.xml中设置inverse=投入额,那么代表customer与order的关系由order来维护,就是说如果采用Customer c=customerDao.findById("1"),c.getOrders.add(new Order()),那么在数据库层面表现为,首先假设在order表格中customer_id可以为空,那么上面的代码会在order表中重保存一条order记录,但是这条纪录中的customer_id=null,这正体现出inverse的设置作用,customer的保存不会维护ustomer与order之间的关系。

 

3.如果在Customer.hbm.xml中设置iverser=false,那么代表customer与order的关系由customer来维护,

还是采用2种说明的代码,那么在数据库中表现为会增加一条order记录,并且这条记录的customer_d不为空.

 

具体代码说明:

1.模型类

public class Customer {

	private String id;

	private String name;

	private Set orders = new HashSet();

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Set getOrders() {
		return orders;
	}

	public void setOrders(Set orders) {
		this.orders = orders;
	}
}

 

 

public class Order {

	private String id;

	private Customer customer;

	private String address;

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}
}
 

 

1.配置文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
	Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
	<class name="domain.Customer" table="customers" catalog="blogday">
		<id name="id">
			<column name="id" />
			<generator class="native"></generator>
		</id>
		<property name="name">
			<column name="name" length="20" />
		</property>
		<set name="orders" lazy="true" inverse="true" cascade="all">
			<key column="customer_id" />
			<one-to-many class="domain.Order" />
		</set>
	</class>
</hibernate-mapping>
 
 
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
	Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
	<class name="domain.Order" table="orders" catalog="blogday">
		<id name="id">
			<column name="id" />
			<generator class="native"></generator>
		</id>
		<property name="address">
			<column name="address" length="20" />
		</property>
		<many-to-one name="customer" column="customer_id"
			class="domain.Customer" cascade="none" />
	</class>
</hibernate-mapping>
 

3.测试代码

public void testSaveOrdersByInverse_Error_Method() {
		Exception e = null;
		Customer c = customerDao.findById("1");
		Order order = new Order();
		Order order2 = new Order();
		c.getOrders().add(order2);
		c.getOrders().add(order);
		try {
			customerDao.save(c);
			customerDao.getHibernateTemplate().flush();
		} catch (Exception e1) {
			e = e1;
		}
		assertNotNull(e);
	}
	 

4. 结果说明

 

4.1  如果设置invserse=true,那么方法testSaveOrdersByInverse_Error_Method()在测试的时候

customerDao.getHibernateTemplate().flush()进行flush的时候会发生错误,错误原因是在order表格中

不允许customer_id=null,而在此时方法testSaveOrdersByInverse_Error_Method会级联保存order记录,但是保存的order记录中hibernate却设置customer_id=null,这也说明了inverse=true说明customer不负责与order之间的引用关系,只是简单的保存记录,并没有建立起二者之间的关系.

 

4.2如果设置inverse=false,说明customer与order之间的关系由customer来维护,那么上面的测试方法testSaveOrdersByInverse_Error_Method()不但会保存相应的order记录,并且order记录中的customer_id也不为空.

 

5.性能考虑

 

5.1 如果设置inverse=true,用如下代码测试

public void testSaveOrdersByInverse_Right_method() {
		Exception e = null;
		Customer c = customerDao.findById("1");
		Order order1 = new Order();
		Order order2 = new Order();
		c.getOrders().add(order1);
		c.getOrders().add(order2);
		order1.setCustomer(c);
		order2.setCustomer(c);
		try {
			customerDao.save(c);
			customerDao.getHibernateTemplate().flush();
		} catch (Exception e1) {
			e = e1;
		}
		assertNull(e);
	}

   测试结果为:

 

Hibernate: select orders0_.customer_id as customer3_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.address as address1_0_, orders0_.customer_id as customer3_1_0_ from blogday.orders orders0_ where orders0_.customer_id=?
Hibernate: insert into blogday.orders (address, customer_id) values (?, ?)
Hibernate: insert into blogday.orders (address, customer_id) values (?, ?)
    说明没插入一条order只需要执行一次插入操作,没有额外的代码执行.

 

5.2 如果设置inverse=false,也顺便设置数据库中order表格中customer_id可以为空,这样下面的代码才不会 抛出错误

public void testSaveOrdersByInverse_Error_Method() {
		Exception e = null;
		Customer c = customerDao.findById("1");
		Order order1 = new Order();
		Order order2 = new Order();
		c.getOrders().add(order1);
		c.getOrders().add(order2);
		try {
			customerDao.save(c);
			customerDao.getHibernateTemplate().flush();
		} catch (Exception e1) {
			e = e1;
		}
		assertNull(e);
	}

 测试结果:

Hibernate: select customer0_.id as id0_0_, customer0_.name as name0_0_ from blogday.customers customer0_ where customer0_.id=?
Hibernate: select orders0_.customer_id as customer3_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.address as address1_0_, orders0_.customer_id as customer3_1_0_ from blogday.orders orders0_ where orders0_.customer_id=?
Hibernate: insert into blogday.orders (address, customer_id) values (?, ?)
Hibernate: insert into blogday.orders (address, customer_id) values (?, ?)
Hibernate: update blogday.orders set customer_id=? where id=?
Hibernate: update blogday.orders set customer_id=? where id=?

 

 

插入customer也会相应的插入order记录,这个在上面已经说明.但是看这里多出了两条update语句,针对每一个孩子都去更新父亲的id明显速度很慢,因为父亲有个孩子的集合,他无法知道哪个孩子的父亲id已经指向自己了,所以对于每一个孩子,都要更新父 亲使他只想自己,而这个关系由孩子维护就好多了,每个孩子只有一个父亲,只有设置过的才需要更新,所以显然,这个父子关系由孩子来维护比较省力.减轻了数 据库的负担.

 

 

正对以上情况在设置one-many或者many-one或者many-many的时候需要谨慎用inverse,而且从性能上来说一般还是有字节点来维护与父节点的关系比较好如下代码就可以简单而且高效来建立二者之间的关系.

 

	public void testSave() {
		Customer customer = customerDao.findById("1");
		Order order = new Order();
		order.setCustomer(customer);
		orderDao.save(order);
		assertNotNull(order.getId());
	}
 

这里的操作很简单而且数据库操作也仅有一条查询语句和一条插入语句.

 

Hibernate: select customer0_.id as id0_0_, customer0_.name as name0_0_ from blogday.customers customer0_ where customer0_.id=?
Hibernate: insert into blogday.orders (address, customer_id) values (?, ?)
 

 

 

 

 

 

 

 

 

 

分享到:
评论
1 楼 crabboy 2008-12-31  
清楚明了。

相关推荐

    NHibernate Inverse & Cascade

    "NHibernate Inverse & Cascade"是两个关键概念,对于理解和有效使用NHibernate至关重要。 **Inverse属性** Inverse属性主要用于控制NHibernate如何处理关联对象的持久化。在一对多或多对一的关系中,当一个实体...

    inverse_c语言inverse_inverse在C_cinverse_c语言longinverse_反插值_

    在这个主题中,我们关注的是一个使用C语言实现的反插值程序,名为"inverse",它似乎对常规的反插值方法进行了优化,加入了正则化处理,以提高计算效果。 首先,让我们理解什么是反插值。在插值中,我们通常有一个...

    彻底明白Hibernate中的Inverse

    在Hibernate中,`Inverse`是一个重要的概念,它涉及到实体之间的关联管理。本文将深入探讨`Inverse`属性,以及它在Hibernate中的作用和应用场景。 一、Hibernate与对象关系映射 Hibernate通过ORM机制将Java对象与...

    hibernate inverse和cascade的详细讲解

    ### Hibernate Inverse 和 Cascade 的详细讲解 #### 一、引言 在ORM(Object-Relational Mapping)领域,Hibernate作为一款流行的Java持久层框架,它提供了丰富的API和配置选项来帮助开发者实现对象与数据库表之间...

    inverse=true的总结

    在IT行业中,尤其是在Java开发或者使用ORM框架(如Hibernate)时,“inverse=true”是一个非常重要的概念,它涉及到对象关系映射中的数据管理策略。本文将深入解析“inverse=true”的含义,以及它在实际应用中的作用...

    Inverse Problem Theory and Methods for Model Parameter Estimation

    **标题:** "Inverse Problem Theory and Methods for Model Parameter Estimation"(反演问题理论与模型参数估计方法) 此书名表明了该书的核心内容是关于反演问题的理论及其在模型参数估计中的应用方法。反演问题...

    PARAMETER ESTIMATION AND INVERSE PROBLEMS(2013)

    This textbook evolved from a course in geophysical inverse methods taught during the past two decades at New Mexico Tech, first by Rick Aster and, subsequently, jointly between Rick Aster and Brian ...

    Parameter estimation and inverse problems

    在科学和工程领域中,参数估计与反问题(Parameter Estimation and Inverse Problems)是解决实际问题的重要工具之一。这类问题通常涉及未知参数或状态的确定,这些参数或状态无法直接测量,但可以通过观察到的数据...

    Inverse Synthetic Aperture Radar Imaging----Victor C. Chen 源代码

    Inverse Synthetic Aperture Radar Imaging----Victor C. Chen 第一章 ISAR成像介绍 第二章 ISAR成像基本原理 第三章 ISAR成像 第四章 ISAR运动补偿 第五章 ISAR自聚焦方法 第六章 ISAR成像中的信号处理问题 第七章...

    inverse和cascade使用阐述

    在IT领域,"inverse"和"cascade"是两个常见的概念,尤其在数据库设计、软件工程以及数据处理中。这两个术语通常与关系型数据库中的外键约束、对象关系映射(ORM)工具,以及某些编程框架的特性相关。下面将详细阐述这...

    IND Inverse - MetaTrader 4脚本.zip

    "IND Inverse - MetaTrader 4 脚本.zip" 是一个包含 MetaTrader 4 (MT4) 平台使用的自定义指标的压缩文件。这个指标被称为 "IND Inverse Indicator",它专为外汇交易者设计,帮助他们在市场分析中做出更明智的决策。...

    JavaEE学习笔记之Hibernate表关系之一对多(inverse详解)

    本文将深入探讨Hibernate中的一对多关系,并重点解析`inverse`属性的作用及其应用。 一对多关系是数据库设计中常见的关联类型,例如一个用户可以拥有多个订单,一个班级可以包含多个学生等。在Hibernate中,通过...

    ISARLAB-Inverse Synthetic Aperture Radar Simulation and Processing Tool

    逆合成孔径雷达(ISAR,Inverse Synthetic Aperture Radar)是一种能够生成目标高分辨率图像的技术,广泛应用于军事、航空以及海洋监控等领域。ISARLAB是一款由澳大利亚国防科学技术组织(DSTO)开发的计算机程序,...

    inverse 例子

    在Hibernate这个强大的对象关系映射(ORM)框架中,`inverse`属性是一个非常重要的概念,它主要用于管理关联关系的维护责任。在这个例子中,我们将会深入理解`inverse`属性的作用,并通过一个简单的测试案例——`...

    A Qualitative Approach to Inverse Scattering Theory

    "A Qualitative Approach to Inverse Scattering Theory" 这本书通过定性方法探讨了逆散射理论,定性方法通常强调于从物理现象中得到定性的结论,而不完全依赖精确的数学表达式。这种方法有助于理解逆散射问题的深层...

    Inverse_Modified_;逆运动学_matlab_Modified_

    "Inverse_Modified" 指的可能是对标准逆运动学算法的一种改进或调整,以适应特定的机器人模型或优化性能。 MATLAB Robotic Toolbox 是一个强大的工具包,提供了各种用于机器人建模、仿真和控制的函数和类。它包含了...

Global site tag (gtag.js) - Google Analytics