save(),saveOrUpdate(),merge()的区别
Save
save()方法能够保存实体到数据库,正如方法名称save这个单词所表明的意思。我们能够在事务之外调用这个方法,这也是我不喜欢使用这个方法保存数据的原因。假如两个实体之间有关系(例如employee表和address表有一对一关系),如果在没有事务的情况下调用这个方法保存employee这个实体,除非调用flush()这个方法,否则仅仅employee实体会被保存。
saveOrUpdate
saveOrUpdate()方法会执行插入或者更新操作。如果该对象在数据库中已经存在则更新,不存在则插入。
saveOrUpdate()方法可以在没有事务的情况下执行,但是如果没有手动调用flush()方法会面临关联对象不被保存的问题
save()方法与saveOrUpdate()方法最大的不同点在于,saveOrUpdate()方法会将实体对象添加到持久化上下文中,该实体的后续改变会被跟踪。
HibernateSaveOrUpdateExample.java
以下是简单的hibernate程序,演示saveOrUpdate()方法的使用。
/*
* @(#)HibernateSaveOrUpdateExample.java Created on 2016年4月10日
* Copyright (c) 2016. All rights reserved.
*/
package nd.esp.com.hibernate.example; import nd.esp.com.hibernate.model.Address;
import nd.esp.com.hibernate.model.Employee;
import nd.esp.com.hibernate.utils.HibernateUtil; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction; public class HibernateSaveOrUpdateExample {
public static void main(String[] args) {
// Prep Work
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
System.out.println("***********************************************");
// saveOrUpdate example - without transaction
Session session5 = sessionFactory.openSession();
Employee emp5 = getTestEmployee();
session5.saveOrUpdate(emp5);
System.out.println("***********************************************"); // saveOrUpdate example - with transaction
Session session3 = sessionFactory.openSession();
Transaction tx3 = session3.beginTransaction();
Employee emp3 = getTestEmployee();
session3.saveOrUpdate(emp3);
emp3.setName("Kumar"); // will be saved into DB
System.out.println("9. Before committing saveOrUpdate transaction. Id=" + emp3.getId());
tx3.commit();
System.out.println("10. After committing saveOrUpdate transaction");
System.out.println("***********************************************"); Transaction tx4 = session3.beginTransaction();
emp3.setName("Updated Test Name"); // Name changed
emp3.getAddress().setCity("Updated City");
session3.saveOrUpdate(emp3);
emp3.setName("Kumar"); // again changed to previous value, so no Employee update
System.out.println("11. Before committing saveOrUpdate transaction. Id=" + emp3.getId());
tx4.commit();
System.out.println("12. After committing saveOrUpdate transaction");
System.out.println("***********************************************"); // Close resources
sessionFactory.close();
}
public static Employee getTestEmployee() {
Employee emp = new Employee();
Address add = new Address();
emp.setName("Test Emp");
add.setCity("Test City");
emp.setAddress(add);
add.setEmployee(emp);
return emp;
}
}
执行上述示例程序,输出结果。
***********************************************
Hibernate: insert into EMPLOYEE (emp_name) values (?)
***********************************************
Hibernate: insert into EMPLOYEE (emp_name) values (?)
9. Before committing saveOrUpdate transaction. Id=21
Hibernate: insert into ADDRESS (city, emp_id) values (?, ?)
Hibernate: update EMPLOYEE set emp_name=? where emp_id=?
10. After committing saveOrUpdate transaction
***********************************************
11. Before committing saveOrUpdate transaction. Id=21
Hibernate: update ADDRESS set city=? where emp_id=?
12. After committing saveOrUpdate transaction
***********************************************
注意如果没有事务,仅仅是employee实体被保存到数据库,而address的信息丢失了。
在事务tx4中的几行代码employee实体的name属性先被修改为“Updated Test Name”,之后又被赋值为原来的值“Kumar”,因此employee这个实体在事务提交之前并没有改变,所以并没有update操作。
下面来讲讲Hibernate的merge方法。我打算按照hibernate对象生命周期的三个状态来讲。
1:如果POJO对象处于游离态,我所说的游离态是指该对象的id值为空。hibernate判断一个对象在数据库中是否存在不是看对象的其他信息,而是判断该id在数据库中是不是存在。如果id为空,那自然是不存在,所以当我们调用merge方法的时候,就会直接执行插入操作。这一点有点像saveorupdate()方法。看一段代码:
再看hibernate的sql语句:
二:脱管态:如果我们把上面代码里//user.setId(4);的注释去掉,那么它就变成了脱管的对象了(其实从游离到脱管就这么简单,没有官方说的那么邪乎...)。这是我们再来看控制台的sql打印:
看到没有,因为id不为空了,所以hibernate就不会再insert了。由于该对象的信息和数据库里的一模一样,所以hibernate只执行了一个select语句,并没有update,如果我们把字段的值做稍微的变动,那么控制台打印的sql语句还应该有一条update语句。就这一点来说,merge还有和saveorupdate()方法一样。
三:持久态:持久态更好理解。如果我们从数据库里get一条记录,那么这条记录就处于持久态,如果再调用merge,那么hibernate就会先判断该记录是否被修改,没有则什么也不干,修改了就update。这一点还是和saveorupdate()有点像。
- Session session = this.getSession();
- Transaction tr = session.beginTransaction();
- User exituser = (User)session.get(User.class, new Integer(1));
- exituser.setAge(11);
- session.merge(exituser);
- tr.commit();
- session.close();
- Session session = this.getSession();
- Transaction tr = session.beginTransaction();
- User exituser = (User)session.get(User.class, new Integer(1));
- exituser.setAge(11);
- session.merge(exituser);
- tr.commit();
- session.close();
再看控制台打印结果:
如果没有对记录进行修改则不会有后面的那条update语句。
那么merge和saveorupdate()到底有什么区别呢?看一段代码:
运行上面的代码,hibernate给我们报了一个错误:a different object with the same identifier value was already associated with the session。意思是,在session缓存中以两个标识相同的对象,这是不可以的。那么,吧update改成merge会怎么样呢?改为merge后,一切OK,运行正常。其实merge在执行更新之前会将两个标识符相同的对象进行合并,具体合并的方向是向exituser2合并。
save(),saveOrUpdate(),merge()的区别的更多相关文章
- Hibernate里save(),saveOrUpdate(),merge(),update()的区别
save()方法用于将一个临时对象转变为持久化对象,也就是将一个新的业务实体保存到数据库中:update()方法用于将一个游离对象重新转变为持久化对象,也就是更新一个已经存在的业务实体到数据库中:sa ...
- Hibernate save()、saveOrUpdate()、merge()的区别
一. update 和 merge的区别 首先在执行更新操作的时候,两者都必须要有id update是直接执行update 语句,执行后状态为持久化状态 而merge则不一样: 1. 如果sessio ...
- Hibernate三种状态的区分,以及save,update,saveOrUpdate,merge等的使用 引自http://www.blogjava.net/TiGERTiAN/archive/2008/10/25/236519.html
Hibernate的对象有3种状态,分别为:瞬时态(Transient). 持久态(Persistent).脱管态(Detached).处于持久态的对象也称为PO(Persistence Object ...
- hibernate中load,get;find,iterator;merge,saveOrUpdate,lock的区别
hibernate中load,get;find,iterator;merge,saveOrUpdate,lock的区别 转自http://www.blogjava.net/bnlovebn/archi ...
- Hibernate三种状态的区分,以及save,update,saveOrUpdate,merge等的使用
Hibernate的对象有3种状态,分别为:瞬时态(Transient). 持久态(Persistent).脱管态(Detached).处于持久态的对象也称为PO(Persistence Object ...
- 论Sava(),SaveOrUpdate(),Merge()区别
一.Save(): 用于将一个临时对象转变为持久化对象,也就是将一个新的业务实体保存到数据库中:相当于jdbc的insert. <假如两个实体之间有关系(例如employee表和address表 ...
- save(),saveorupdate()还有marqe()
所有这三个方法,也就是save().saveOrUpdate()和persist()都是用于将对象保存到数据库中的方法,但其中有些细微的差别.例如,save()只能INSERT记录,但是saveOrU ...
- save()、saveOrUpdate()、merge()的区别
一.Save() save()方法能够保存实体到数据库.假如两个实体之间有关系(例如employee表和address表有一对一关系),如果在没有事务的情况下调用这个方法保存employee这个实体, ...
- save与 merge与 saveOrUpdate的区别
save()方法很显然是执行保存操作的,如果是对一个新的刚new出来的对象进行保存,自然要使用这个方法了,数据库中没有这个对象. update()如果是对一个已经存在的托管对象进行更新那么肯定是要使用 ...
随机推荐
- 背水一战 Windows 10 (31) - 控件(按钮类): ButtonBase, Button, HyperlinkButton, RepeatButton, ToggleButton, AppBarButton, AppBarToggleButton
[源码下载] 背水一战 Windows 10 (31) - 控件(按钮类): ButtonBase, Button, HyperlinkButton, RepeatButton, ToggleButt ...
- Java异常处理机制 try-catch-finally 剖析
Java拥有着强大的异常处理机制,最近初步学习了下,感觉内容还是挺多的,特此来将自己的理解写出来与大家分享. 一. 在Java代码code中,由于使用Myeclipse IDE,可以自动提醒用户哪里有 ...
- UVALive 6911---Double Swords(贪心+树状数组(或集合))
题目链接 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- Ant搭建 一键生成APP技术 平台
1.博客概要 本文详细介绍了当今流行的一键生成APP技术.介绍了这种设计思想的来源,介绍了国内外的研究背景,并介绍了这个技术体系中的一些实现细节,欢迎各路大神们多提意见.一键生成技术,说的通俗点就是, ...
- 初识Spring MVC
1.什么是Spring MVC? Spring MVC属于SpringFrameWork的后续产品,它提供了构建 Web 应用程序的全功能 MVC 模块,与Struts2一样是一种优秀MVC框架,不同 ...
- 在易语言中调用MS SQL SERVER数据库存储过程方法总结
Microsoft SQL SERVER 数据库存储过程,根据其输入输出数据,笼统的可以分为以下几种情况或其组合:无输入,有一个或多个输入参数,无输出,直接返回(return)一个值,通过output ...
- Android中Listview点击item不变颜色以及设置listselector 无效
Android中Listview点击item不变颜色以及设置listselector 无效 这是同一个问题,Listview中点击item是会变颜色的,因为listview设置了默认的listsele ...
- 从tabBarController的一个item上的控制器跳转到另一个item上的控制器
先从习惯性的tabBarController开始,很多应用的外框都是用这个开始的,而从tabBarController的一个item上的控制器跳转到另一个上的,往往都是直接通过点击tabBar上的不同 ...
- 基于Ruby的Watir-WebDriver自动化测试框架
基于Ruby的watir-webdriver自动化测试方案与实施(五) 基于Ruby的watir-webdriver自动化测试方案与实施(四) 基于Ruby的watir-webdriver自动 ...
- linux 学习随笔-shell简单编写
脚本最好都放在/usr/local/sbin中 脚本的执行 sh -x 脚本.sh -x可以查看执行过程 1在脚本中使用变量 使用变量的时候,需要使用$符号: #!/bin/bash ##把命令赋 ...