`

主题:inverse

阅读更多

前不久在搭建系统框架的时候遇到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.模型类

Java代码 复制代码

 

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;
	}
}

 

 

Java代码 复制代码

 

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.配置文件

Java代码 复制代码

<?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>
 

 

Java代码 复制代码
<?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.测试代码

Java代码 复制代码

       

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,用如下代码测试

Java代码 复制代码

 

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

   测试结果为:

 

Java代码 复制代码

 

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可以为空,这样下面的代码才不会 抛出错误

Java代码 复制代码

  

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

 测试结果:

Java代码 复制代码

 

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,而且从性能上来说一般还是有字节点来维护与父节点的关系比较好如下代码就可以简单而且高效来建立二者之间的关系.

 

Java代码 复制代码

 

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

 

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

 

Java代码 复制代码

 

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 (?, ?)

 

分享到:
评论

相关推荐

    Discrete Inverse Problems, Insight and Algorithms.pdf清晰版

    本书覆盖了从数值分析到科学计算的一系列主题,适合于研究人员、实践者以及高级数学、工程和计算科学领域的本科生。 #### 1. 数值方法介绍 书中不仅提供了用于解决问题的方法或方法类别的数学背景,还解释了如何将...

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

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

    inverse和cascade使用阐述

    在压缩包文件“inverse_cascade”中,可能包含了与这个主题相关的代码示例、教程文档或者其他资源。这些文件可能帮助读者更深入地理解这两个概念,并能动手实践,从而更好地掌握在实际项目中如何应用“inverse”和...

    Hinton在NIPS2017上关于capsules的演讲PPT:Does the Brain do Inverse Graphics?

    在NIPS 2017会议上,Geoffrey Hinton发表了一篇题为“Does the Brain do Inverse Graphics?”的演讲,该演讲主要探讨了人类视觉和capsules这两个核心主题。本文将从以下几个方面详细解释这一主题中所涉及的知识点。...

    A Qualitative Approach to Inverse Scattering Theory

    本书中也提到了一些数学主题分类,如35P25(逆谱问题)、35R25(偏微分方程的逆问题)、35R30(其他偏微分方程的逆问题)、65M30(有限差分方法的逆问题)、65R30(边界值问题和谱理论的逆问题)、78A45(声学和电磁...

    Inverse Synthetic Aperture Radar Imaging With MATLAB Algorithms

    本主题主要探讨了使用MATLAB作为工具来实现ISAR成像的算法。 MATLAB是一种广泛使用的编程环境,特别适合于数值计算、图像处理和算法开发。在ISAR成像中,MATLAB的优势在于其强大的信号处理库和可视化功能,使得...

    Inverse Scattering Opti.zip_Inverse Scattering_scattering_time r

    这个主题通常涉及从散射信号中恢复原始物体的信息。在“Inverse Scattering Opti.zip”压缩包中,我们可能找到关于逆散射优化算法和时间反转成像的详细资料。 时间反转成像是逆散射的一个关键分支,它利用了时间...

    Qualitative Methods in Inverse Scattering Theory

    这本书深入探讨了这一主题,提供了一套全面的定性方法来理解和解决反散射问题。 反散射理论主要关注的是,当入射波(如声波、电磁波或地震波)遇到不均匀介质时,如何通过分析回波信息来推断介质的特性。它在诸如...

    Differential Equations Inverse and Direct Problems

    “Differential Equations Inverse and Direct Problems”这一标题明确指出本书的主题聚焦于微分方程领域中的两个重要方面:逆问题(inverse problems)与正问题(direct problems)。微分方程作为数学分析的一个核心...

    Robotics Inverse Kinematics Subproblems 0 to 2:Robotics Inverse Kinematics Subproblems 0 to 2-matlab开发

    这个主题通常分为多个子问题,以便更好地理解和解决。本项目聚焦于"Robotics Inverse Kinematics Subproblems 0 to 2",并结合MATLAB环境进行开发,这将有助于我们深入理解逆运动学的基础及其在实际应用中的实现。 ...

    主题模型Python工具包Gensim.zip

    Gensim是一个相当专业的主题模型Python工具包。在文本处理中,比如商品评论挖掘,有时需要了解每个评论分别和商品的描述之间的相似度,以此衡量评论的客观性。评论和商品描述的相似度越高,说明评论的用语比较官方,...

    assoc_mem.zip_autoassociative_memory_pseudoinverse

    在这一主题中,我们将深入探讨这两个关键概念以及它们在实际应用中的作用。 自动联想记忆是一种人工神经网络模型,其主要目标是学习输入向量与其对应的输出向量之间的映射关系。这种映射通常是自对称的,即输入和...

    Parameter Estimation and Inverse Problems, Second Edition对应的第7章代码

    这些主题在许多领域,如地球物理学、医学成像、信号处理和环境科学中都有广泛应用。以下是第7章涉及的一些关键知识点: 1. **参数估计**:这是统计学中的一个重要概念,旨在通过观测数据来确定模型中的未知参数。有...

    hair_inverse_video.rar_Hair!

    "标签可能是指项目开发者或团队的标识,或者与项目主题有关的特定技术点。 描述中的信息指出,这个压缩包包含的是在DM642开发板上实现视频图像反转功能的相关代码或文档。在数字视频处理中,图像反转通常指的是将...

    ACTIVITY3-Inverse-Laplace-Transforms_transform_

    这个主题属于信号处理、控制系统理论或数学分析的范畴,特别是在解决微分方程时特别有用。逆拉普拉斯变换是将复频域表示转换回时间域的过程,对于理解和分析动态系统至关重要。 **逆拉普拉斯变换定义** 逆拉普拉斯...

    28.基于LDA和pyLDAvis的主题挖掘及可视化1

    在预处理后,通常会计算词频和TF-IDF(Term Frequency-Inverse Document Frequency)值。词频反映一个词在文档中出现的频率,而TF-IDF考虑了词在整个文档集合中的普遍性,降低常见词汇的重要性,提升独特词汇的权重...

    Matrix Determinant, Inverse, Trace, and Rank

    在MATLAB教程中,"Matrix Determinant, Inverse, Trace, and Rank"这一主题通常会涵盖如何计算这些属性,以及它们在实际问题中的应用。通过观看提供的视频教程和阅读相应的字幕,你可以深入理解这些概念,并学习如何...

    Parameter Estimation and Inverse Problems

    - **高级主题**:对于希望深入了解特定领域的读者来说,每章末尾提供的“笔记和进一步阅读”部分可以引导他们进行更深入的研究。 - **数学背景要求**:考虑到本书的目标读者群体,作者们有意避免了过于复杂的数学...

    主题词抽取

    在主题词抽取方面,NLTK提供了TF-IDF(Term Frequency-Inverse Document Frequency)算法,这是一种常用的关键词提取方法,通过计算词汇在整个文档集中的出现频率和文档频率来评估其重要性。 2. spaCy:这是一个...

Global site tag (gtag.js) - Google Analytics