两个持久化类。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. Java动态代理的理解

    代码内容: https://github.com/cjy513203427/Java_Advanced_Knowledge/tree/master/src/com/advance/dynamic_pr ...

  2. Error:All flavors must now belong to a named flavor dimension.

    环境 android studio 3.0 错误 Error:All flavors must now belong to a named flavor dimension. 解决 在build.gr ...

  3. Boxlayout中button改变大小

    需要先设置maximunsize neuStart.setBorder(BorderFactory.createRaisedBevelBorder()); neuStart.setMaximumSiz ...

  4. poj 3260 最少硬币(01+多重+完全背包)

    http://www.cnblogs.com/ACMan/archive/2012/08/14/2637437.html #include <iostream> #include < ...

  5. java IO流实现删除文件夹以及文件夹中的内容

    这篇主要是对IO文件流对文件常用处理中的删除文件夹,平时我们直接删除文件夹既可以删除里面的全部内容. 但是java在实现删除时,只能是文件才会被删除. 所以这里需要定义一个方法,来递归调用方法(递归调 ...

  6. css3之背景定位

    属性: background-position: left top || left bottom || right top || right bottom || center center || 像素 ...

  7. Grunt usemin前端自动化打包流程

    前端优化是尽量减少http请求,所以我们需要尽量合并压缩文件,然后调用压缩后的文件,比如多个css文件压缩成一个,多个js文件合并压缩等,usemin能够自动在html中使用压缩后的文件,达到上面的目 ...

  8. Stirling数

    第一类: 定义 第一类Stirling数表示表示将 n 个不同元素构成m个圆排列的数目.又根据正负性分为无符号第一类Stirling数    和带符号第一类Stirling数    .有无符号Stir ...

  9. LinqToSql EntityFramework(ef)查看生成的sql语句

    var dc=new DBDataContext(); TextWriter tw = new StringWriter(); dc.Log = tw; var list = dc.News.Skip ...

  10. JS原生隐藏显示图片,点击切换图片的效果

    今天要说的内容,看标题就都能知道了!所有知识点一览无遗啊!咱们今天的东西,是纯纯的原生JS代码, 我先说一下要求, 1.有两个按钮,内容为显示,和换, 2.当点击显示的时候,按钮文字变成隐藏,同时图片 ...