两个持久化类。Customer 和 OrderForm

Customer 类。

package com.zcd.hibernate.manyToOne;

public class Customer
{
private Integer id;
private String name; public Customer()
{
} public Customer(String name)
{
this.name = name;
} public Customer(Integer id, String name)
{
this.id = id;
this.name = name;
}  //这里省略掉getter 和 setter 方法 }

OrderForm 类

package com.zcd.hibernate.manyToOne;

public class OrderForm
{
private Integer id;
private String name;
private Customer customer; public OrderForm()
{
} public OrderForm(String name, Customer customer)
{
this.name = name;
this.customer = customer;
} public OrderForm(Integer id, String name, Customer customer)
{
this.id = id;
this.name = name;
this.customer = customer;
} //这里省略掉getter 和 setter 方法 }

Customer 和 OrderForm 类的DAO 方法就是没有特别之处,这里也省略的。

//=======================分割线==========================================

下面是测试类调用Service 层。

Service 层的业务方法

public void save(Customer customer, OrderForm orderForm)
{
/*
* OrderForm 为多端, Customer 为一端
* 这里先保存一端,再保存多端。
*/ customerDao.save(customer);
orderFormDao.save(orderForm);
}

观察现象:这是基于以上 先保存一端,再保存多端的 Service 层的方法的。

//这个方法执行后有两条INSERT语句,能正常保存。
@Test
public void testInsert()
{
Customer customer = new Customer(1, "顾客"); OrderForm orderForm = new OrderForm(1, "订单1", customer); testService.save(customer, orderForm);
}
//但是有一个地方需要注意,如果不做任何改变,继续执行这个方法一次,这里虽然还是指定新建的Customer 对象的id 为1,
//OrderForm 对象的id 也为1,但是由于是新建的对象,所以在数据库里的他们的id 并不是1,都会在原来的表的基础上加1。比如这里他们的id 都为2,
//那么此时orderform 表中的 id 为 2 的这条数据的外键列的是指向customer 表中的 id 为1 的数据还是 id 为2 的那条数据呢?实际上结果如下图。
//此时orderform 表中的id为2的数据的外键列指向的是customer表中的id为2的那条数据。个人认为是因为,在第二次保存的 orderForm 对象中的属性就是
//第二次保存的customer对象,而那个对象的保存在数据表中的id 为2,所以外键列的值也为2.

------------------------------------------------------------------------------------------------------------------------

如果在新建的对象中没有指定id,代码如下

@Test
public void testInsert()
{
Customer customer = new Customer("顾客3");//没有指定id OrderForm orderForm = new OrderForm("订单3", customer);//没有指定id testService.save(customer, orderForm);
}

此时正常保存,需要注意的是,此时也只想数据库发送了两条INSERT 语句(因为这是先保存一端,再保存多端的决定的。),现在看一下,修改Service层,先保存多端,在保存一端.

public void save(Customer customer, OrderForm orderForm)
{
/*
* OrderForm 为多端, Customer 为一端
* 这里先保存多端,再保存一端。
*/ orderFormDao.save(orderForm);
customerDao.save(customer);
}

此时正常保存,但是向数据库发送了两条INSERT 语句和一条UPDATE语句,说明先保存多端再保存一端的时候性能下降了。

================================2017-09-24更============================

为什么先保存多端在保存一端的时候性能会下降呢?

应该是这两个类的关联关系是由多端维护的(也就是在多端的表中有一个外键列保存了一端的ID,因为这样才能把两者关联起来。)

如果我们先保存多端,此时它关联的一端的那条记录还没保存,所以一端的那条记录的ID还没有确定。此时多端的表中的那条记录的外键列还是空的。所以得等到一端保存后再对多端进行更新。

Hibernate多对一关联关系的更多相关文章

  1. 关于Hibernate多对多关联关系的更新问题。

    一个账套类Reckoning和账套项目类 AccountItem.这两个类是双向多对多关联关系. Reckoning.hbm.xml文件的配置如下 <set name="account ...

  2. Hibernate多对多关联关系

    今天遇到一个问题:有一个的类Reckoning,一个类AccountItem.这两个类之间的关系时多对多的关联关系. 一开始是由AccountItem来维护关联关系的,也就是Reckoning.hbm ...

  3. Hibernate(6)—— 一对多 和 多对多关联关系映射(xml和注解)总结

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: One to Many 映射关系 多对一单向外键关联(XML/Annotation) 一对多单向外键关联(XM ...

  4. Hibernate—— 一对多 和 多对多关联关系映射(xml和注解)总结(转载)

    One to Many 映射关系 多对一单向外键关联(XML/Annotation) 一对多单向外键关联(XML/Annotation) 懒加载和积极加载 一对多双向外键关联(XML/Annotati ...

  5. 【SSH三大框架】Hibernate基础第六篇:多对一关联关系的映射、分析及加入、查询

    这里举样例用的是:部门与员工的关系. 一个部门能够相应多个员工,这就是非常明显的多对一关联关系. 我们须要建立两个实体类:员工(Employee).部门(Department) 员工类:Employe ...

  6. Hibernate-ORM:12.Hibernate中的多对多关联关系

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客将讲述Hibernate中的多对多关联关系的操作,准备的篇幅较少,望海涵 一,讲述多对多 多对多的关联 ...

  7. (转)Hibernate框架基础——多对多关联关系映射

    http://blog.csdn.net/yerenyuan_pku/article/details/52756536 多对多关联关系映射 多对多的实体关系模型也是很常见的,比如学生和课程的关系.一个 ...

  8. Hibernate双向一对多、双向多对多关联关系中的映射文件怎么写

    这里以一对多关联关系为例.以Country类为一端,Competition类为多端. 一个国家可以有多个赛事,但是一个赛事只能属于一个国家. Country类 public class Country ...

  9. hibernate多对一双向关联

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

随机推荐

  1. linux下MySQL停止和重启

    一.启动方式1.使用linux命令service 启动:service mysqld start2.使用 mysqld 脚本启动:/etc/inint.d/mysqld start3.使用 safe_ ...

  2. render函数的使用

    render函数的几种使用方法最近使用element-ui的tree组件时,需要在组件树的右边自定义一些图标,就想到了用render函数去渲染. <el-tree class="p-t ...

  3. 巧用CheckedTextView完成自定义radiobutton的listview

    因为要用自定义图片的radiobutton的listview,最开始想自己重新写BaseAdapter,重新定义BaseAdapter中的每个list的item.总之android提供了太多方便的控件 ...

  4. Dell解决黑苹果网卡(BCM94352ZAE/DW1560)怎么都打不开WiFi

    Dell解决黑苹果网卡(BCM94352ZAE/DW1560)怎么都打不开WiFi 2017年10月20日17:41:00 by SemiconductorKING 本来觉得驱动这个网卡不是个问题,以 ...

  5. WPF简单的数据库查询

    做一个简单WPF连接数据库的 控件类型和名称:DataGrid:dataGrid          Button1  :Button1              Button:   Button2   ...

  6. Java - 用builder代替构造器

    静态工厂和够构造器有一个共同的局限性:遇到大量的参数时无法很好的扩展. 先说说构造器. 其实field不多时重叠构造器(telescoping constructor)是个不错的方法,易于编写也易于调 ...

  7. 自己实现async和await

    无意当中看了一些博文,说有人想自己尝试实现基于异步操作的方法: 1)直接使用Task(不说咯,这个是微软给我们的标准实现方法). 2)必须继承INotifyCompletion接口,同时自己实现IsC ...

  8. java_对象序列化、反序列化

    1.概念 序列化:将对象转化为字节序列的过程 反序列化:将字节序列转化为对象的过程 用途: A:将对象转化为字节序列保存在硬盘上,如文件中,如文本中的例子就是将person对象序列化成字节序列,存在p ...

  9. Cardinality Estimation算法学习(二)(Linear Counting算法、最大似然估计(MLE))

    在上篇,我了解了基数的基本概念,现在进入Linear Counting算法的学习. 理解颇浅,还请大神指点! http://blog.codinglabs.org/articles/algorithm ...

  10. JS对象原型的理解

    基于原型的语言 JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板.从原型继承方法和属性.原型对象 ...