save(),saveOrUpdate(),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()方法

HibernateSQL

下面来讲讲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. Session session = this.getSession();
  2. Transaction tr = session.beginTransaction();
  3. User exituser = (User)session.get(User.class, new Integer(1));
  4. exituser.setAge(11);
  5. session.merge(exituser);
  6. tr.commit();
  7. session.close();
  1. Session session = this.getSession();
  2. Transaction tr = session.beginTransaction();
  3. User exituser = (User)session.get(User.class, new Integer(1));
  4. exituser.setAge(11);
  5. session.merge(exituser);
  6. tr.commit();
  7. 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合并。

转载于:https://www.cnblogs.com/Smile-123/p/5826763.html

save(),saveOrUpdate(),merge()的区别相关推荐

  1. Hibernate save, saveOrUpdate, persist, merge, update 区别

    Hibernate save, saveOrUpdate, persist, merge, update 区别 - 小黑客 - 博客园 https://www.cnblogs.com/xiaoheik ...

  2. Hibernate三种状态的区分,以及save,update,saveOrUpdate,merge等的使用

    Hibernate的对象有3种状态,分别为:瞬时态(Transient). 持久态(Persistent).脱管态(Detached).处于持久态的对象也称为PO(Persistence Object ...

  3. save()、saveOrUpdate()、merge()的区别

    一.Save() save()方法能够保存实体到数据库.假如两个实体之间有关系(例如employee表和address表有一对一关系),如果在没有事务的情况下调用这个方法保存employee这个实体, ...

  4. Hibernate中saveOrUpdate()和merge()的区别

    this.getSession().merge(obj);this.getSession().saveOrUpdate(obj); saveOrUpdate(): saveOrUpdate()基本上就 ...

  5. Hibernate中保存与持久性以及saveOrUpdate之间的区别

    保存与保存或更新与持久保存在Hibernate中 save和saveOrUpdate之间的区别是什么或save和persist之间的区别是任何Hibernate面试中常见的面试问题,就像Hiberna ...

  6. Hibernate 中upate,savaOrUpdate,merge的区别

    通常下面的场景会使用update()或saveOrUpdate(): 程序在第一个session中加载对象 该对象被传递到表现层 对象发生了一些改动 该对象被返回到业务逻辑层 程序调用第二个sessi ...

  7. Git rebase 和 Git merge 的区别,你知道吗?

    编辑搜图 请点击输入图片描述 Git是大多数程序必备的工具之一,Git常用那么几个命令:pull.push.status.merge.rebase.Git rebase 和 Git merge都是合并 ...

  8. npm 中 --save 与 --save-dev 的区别

    前言 在使用 npm 安装模块包的时候使用 npm install 模块名称 命令.但通常后面会加上 --save 或者 --save-dev,那么这两个命令有什么区别昵?以下是四种安装方式.以 we ...

  9. git merge\git merge --no-commit\git merge --squash区别

    假设现有分支develop.test.需要将test合并到develop分支. 首先git checkout develop. git merge test test分支会合并到develop,会有t ...

最新文章

  1. 想学图像分割,强烈建议从这5篇图像分割算法综述
  2. chrome出现adobe flash playe 不是最新版本
  3. stm32c8t6的can通信实验代码_TCP的连接建立与关闭状态及数据传输通信过程【含有 PHP socket API 测试实验代码】...
  4. Win10 OpenCV3.3.0+VS2013配置大坑,OpenCV解决方案编译报错“找不到python36_d.lib”错误...
  5. 二叉树的一些leetcode题目+python(c++)
  6. WCF在安全性方面的支持(1):一些概念
  7. 【面试】iOS 开发面试题(二)
  8. 数据结构c语言pdf2007,数据结构(C语言)严蔚敏 吴伟明 编著 07.pdf
  9. svn安装使用以及各种问题解决
  10. idea 格式化代码怎么才能不格式化代码注释?
  11. 通过regedt查看计算机密码,教你操作电脑密码查看器 【解决办法】 的还原教程_...
  12. ILSVRC2015_DET.tar.gz下载地址
  13. mysql常用语句梳理
  14. word替换妙用:批量去除多余空格、空行、换行2020-11-30
  15. Datawhale组队学习周报(第029周)
  16. Centos下安装Pure-ftpd
  17. [转|会计学习]资产盘盈、盘亏的会计处理
  18. 每日一题——有效的数独
  19. echart显示多组数据
  20. 复选框 html 操作,HTML页面中复选框的操作方法

热门文章

  1. 安卓手机阅读器_乐应用|安卓手机本地阅读的不二之选
  2. servlet返回数据给html_Servlet 简介
  3. 双向绑定v-bind
  4. 学习10:Python重要知识
  5. 移动端REM布局方案
  6. 微信新的用户信息接口wx.getUserProfile,返回信息解密失败
  7. fragment 调用activity方法,如dispatchKeyEvent,dispatchTouchEvent
  8. android 程序崩溃日记捕捉
  9. vue-cli3配置externals、jquery
  10. 微信支付 签名算法 sign node实现