Save()saveOrUpdate()Hibernate的merge()方法
Save
save()方法能够保存实体到数据库,正如方法名称save这个单词所表明的意思。我们能够在事务之外调用这个方法,这也是我不喜欢使用这个方法保存数据的原因。假如两个实体之间有关系(例如employee表和address表有一对一关系),如果在没有事务的情况下调用这个方法保存employee这个实体,除非调用flush()这个方法,否则仅仅employee实体会被保存。
saveOrUpdate
saveOrUpdate()方法会执行插入或者更新操作。如果该对象在数据库中已经存在则更新,不存在则插入。
saveOrUpdate()方法可以在没有事务的情况下执行,但是如果没有手动调用flush()方法会面临关联对象不被保存的问题
save()方法与saveOrUpdate()方法最大的不同点在于,saveOrUpdate()方法会将实体对象添加到持久化上下文中,该实体的后续改变会被跟踪。
HibernateSaveOrUpdateExample.java
以下是简单的hibernate程序,演示saveOrUpdate()方法的使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
/* * @(#)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; } } |
执行上述示例程序,输出结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
*********************************************** 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()有点像。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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()Hibernate的merge()方法的更多相关文章
- save(),saveOrUpdate(),merge()的区别
Save save()方法能够保存实体到数据库,正如方法名称save这个单词所表明的意思.我们能够在事务之外调用这个方法,这也是我不喜欢使用这个方法保存数据的原因.假如两个实体之间有关系(例如empl ...
- [原创]java WEB学习笔记79:Hibernate学习之路--- 四种对象的状态,session核心方法:save()方法,persist()方法,get() 和 load() 方法,update()方法,saveOrUpdate() 方法,merge() 方法,delete() 方法,evict(),hibernate 调用存储过程,hibernate 与 触发器协同工作
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Hibernate中Session的save()、update()、merge()、lock()、saveOrUpdate()和persist()方法有什么区别?
Hibernate的对象有三种状态:瞬态.持久态和游离态.游离状态的实例可以通过调用save().persist()或者saveOrUpdate()方法进行持久化:脱管状态的实例可以通过调用 upda ...
- Hibernate里save(),saveOrUpdate(),merge(),update()的区别
save()方法用于将一个临时对象转变为持久化对象,也就是将一个新的业务实体保存到数据库中:update()方法用于将一个游离对象重新转变为持久化对象,也就是更新一个已经存在的业务实体到数据库中:sa ...
- Hibernate save, saveOrUpdate, persist, merge, update 区别
Hibernate Save hibernate save()方法能够保存实体到数据库,正如方法名称save这个单词所表明的意思.我们能够在事务之外调用这个方法,这也是我不喜欢使用这个方法保存数据的原 ...
- Hibernate各保存方法之间的差 (save,persist,update,saveOrUpdte,merge,flush,lock)等一下
hibernate保存 hibernate要保存的目的是提供一个方法,多.它们之间有许多不同之处,点击此处详细说明.使得差: 一.预赛: 在所有.阐释.供hibernate,,transient.p ...
- 【hibernate】Hibernate中save, saveOrUpdate, persist, merge, update 区别
Hibernate Save hibernate save()方法能够保存实体到数据库,正如方法名称save这个单词所表明的意思.我们能够在事务之外调用这个方法,这也是我不喜欢使用这个方法保存数据的原 ...
- Hibernate中对象的三种状态以及Session类中saveOrUpdate方法与merge方法的区别
首先,用一张图说明一个对象,在Hibernate中,在调用了不同方法之后对象所处的不同状态 在Hibernate中,一个对象的状态可以被分为如图所示的三种 Transient:瞬时对象,该对象在数据库 ...
- Hibernate: merge方法
在Hibernate中,有save.persist.savaOrUpdate.merge等方法有插入数据的功能.前三者理解起来较后者容易一些,merge方法从api中的介绍就看以看出它是最复杂的.下面 ...
随机推荐
- <%@ page contentType="text/html; charset=utf-8" language="java"%>每一个字符的含义
contentType="text/html:网页类型htmlcharset=utf-8"网页编码类型language="java"网页编程语言<% @ ...
- UVALive 6916---Punching Robot(卢卡斯+容斥)
题目链接 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- BaseAdapter的抽取
为了更方便高效的使用BaseAdapter,特意抽取了一下,下面是简单的结构图: 需要4个类: [MyBaseAdapter3]: public abstract class MyBaseAdapte ...
- PHP规范PSR2
为了尽可能的提升阅读其他人代码时的效率,下面例举了一系列的通用规则,特别是有关于PHP代码风格的.各个成员项目间的共性组成了这组代码规范.当开发者们在多个项目中合作时,本指南将会成为所有这些项目中共用 ...
- AMD and CMD are dead之KMDjs集成Blob一键下载全部build包
更新 不zuo,[A/C]MD就不会死,所以kmdjs赢来来其伟大的版本0.0.6,该版本主要的更新有: 移除去了kmdjs.get(..).then的支持,只支持kmdjs.get(-,functi ...
- 总结常见的ES6新语法特性
前言 ES6是即将到来的新版本JavaScript语言的标准,他给我们带来了更"甜"的语法糖(一种语法,使得语言更容易理解和更具有可读性,也让我们编写代码更加简单快捷),如箭头函数 ...
- 原生JS:JSON对象详解
JSON对象 支持到IE8,旧版的IE需要Polyfill 本文参考MDN做的详细整理,方便大家参考[MDN](https://developer.mozilla.org/zh-CN/docs/Web ...
- HashMap和SparseArray的性能比较。
HashMap和SparseArray可以实现相似的功能. 但SparseArray是Android定义的,在键是整数时,他比HashMap的性能更高,因为HashMap使用的是Integer对象, ...
- Android Gradle Build Error:Some file crunching failed, see logs for details解决办法
转载请标明出处: http://www.cnblogs.com/why168888/p/5925756.html 本文出自:[Edwin博客园] 错误日志:Error:java.lang.Runtim ...
- UITextView 开始编辑时,文字没有左上角对齐解决办法 tableview整体上移
现实情况如上所示 我出现这种情况的原因有两种: 其一:没有给textview对齐方式: 其二:没有将BOOL类型的“ automaticallyAdjustsScrollViewInsets ”属性置 ...