by:rhythmk.cnblogs.com

1、Hibernate 三种状态:

1.1、三种定义(个人理解,不一定准确):

 瞬时状态(transient):    不被session接管,且不存在数据库中的对象的状态,类似于新New一个对象

 离线状态 (detached):    数据库中存在而不被session接管

 持久化状态(persistent): 对象被session管理且数据库中存在此对象

1.2、 状态之间转换关系图

2 、状态转换以及Hibernate数据库执行过程详解:

2.1  瞬时状态 转换为 持久化对象

	/*
* 瞬时状态转换成序列化状态
* */ Session session = null;
try {
session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
User user=new User();
user.setCreateTime(new Date());
user.setName("rhythmk");
user.setOpenId(10);
user.setType("admin");
// 此时User为瞬时对象
session.save(user);
// 通过save方法 user已经转变为持久化对象
session.getTransaction().commit(); } catch (Exception e) {
e.printStackTrace();
} finally {
if (session != null)
session.close(); } }

  

当一个 瞬时对象被转成持久化对象后 ,只要此session会话没有关闭,该对象属性值再发生变化,session提交时候都会去对比该对象于保存时候是否被修改过。

如果被修改,则将该对象最终结果同步到数据库。

参考代码如下,进过在转变为持久化对象后进过多次调用update方法,最终生成的SQL语句依然只会有一个Insert与一条Update:

	@Test
public void test2()
{ Session session = null;
try {
session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
User user=new User();
user.setCreateTime(new Date());
user.setName("rhythmk");
user.setOpenId(10);
user.setType("admin");
// 此时User为瞬时对象
session.save(user);
// 通过save方法 user已经转变为持久化对象 user.setName("updatename");
session.update(user); user.setName("updatename2");
session.update(user); user.setName("updatename3");
session.update(user); session.getTransaction().commit(); } catch (Exception e) {
e.printStackTrace();
} finally {
if (session != null)
session.close(); } }

输出:

  Hibernate: insert into user (openId, type, name, createTime) values (?, ?, ?, ?)

        Hibernate: update user set openId=?, type=?, name=?, createTime=? where userId=?

2.2 、当一个离线对象 通过session.delete方法转换成瞬时对象,此时瞬时对象的值发生变化将不生成同步SQL

@Test
public void test3()
{ Session session = null;
try {
session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
User user = new User();
user.setCreateTime(new Date());
user.setName("rhythmk");
user.setOpenId(10);
user.setType("admin"); user.setUserId(12); session.delete(user);
//此时 user成为瞬时状态 以后其属性值的改变不会再生成SQL语句 user.setName("updatename"); user.setName("updatename3"); session.getTransaction().commit(); } catch (Exception e) {
e.printStackTrace();
} finally {
if (session != null)
session.close(); }
}

输出:

Hibernate: delete from user where userId=?  

当一个离线状态转换成瞬时状态时,改对象属性值发生变化尽管设定了改对象主键值,再调用session.save方法生成的Insert语句将不关注此主键ID

@Test
public void test4() { Session session = null;
try {
session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
User user = new User();
user.setCreateTime(new Date());
user.setName("rhythmk");
user.setOpenId(9);
user.setType("admin"); user.setUserId(9); session.delete(user); user.setName("updatename");
session.save(user); user.setName("updatename3");
session.update(user);
user.setName("updatename32");
session.update(user);
user.setName("updatename33");
session.update(user);
session.getTransaction().commit(); } catch (Exception e) {
e.printStackTrace();
} finally {
if (session != null)
session.close(); } }

  

输出:

Hibernate: delete from user where userId=?
Hibernate: insert into user (openId, type, name, createTime) values (?, ?, ?, ?)
Hibernate: update user set openId=?, type=?, name=?, createTime=? where userId=?

参考方法:

 session.saveOrupdate(object)

根据object对象的主键ID判断如果,数据库存在记录则更新,否则添加

session.merge(object)

如果session回话中已经存在某主键ID的对象,如果此时再添加一个同主键的新对象进如回话状态,将出现异常  ,

此情况则可以调用merge方法对session回话中以存在对象进行覆盖:

如:

session = HibernateUtil.openSession();
session.beginTransaction();
//u1已经是持久化状态
User u1 = (User)session.load(User.class, 3);
System.out.println(u1.getUsername());
//u2是离线状态
User u2 = new User();
u2.setId(3);
u2.setPassword("123456789");
//此时u2将会变成持久化状态,在session的缓存中就存在了两份同样的对象,在session中不能存在两份拷贝,否则会抛出异常
// session.saveOrUpdate(u2);
//merge方法会判断session中是否已经存在同一个对象,如果存在就将两个对象合并
session.merge(u2);
//最佳实践:merge一般不用
session.getTransaction().commit();

  

参考:

http://www.cnblogs.com/xiaoluo501395377/p/3380270.html

Rhythmk 学习 Hibernate 02 - Hibernate 之 瞬时状态 离线状态 持久化状态 三状态的更多相关文章

  1. Hibernate之Session对象的相关方法以及持久化对象的状态

    一.持久化对象的状态        站在持久化的角度, Hibernate 把对象分为 4种状态: 持久化状态,临时状态,游离状态,删除状态.Session 的特定方法能使对象从一个状态转换到另一个状 ...

  2. Rhythmk 学习 Hibernate 05 - Hibernate 表间关系 [ManyToOne,OneToMany]

    1.项目结构: 1.1.场景说明: 一个订单,包含多个产品 1.2.类文件: Order.java package com.rhythmk.model; import java.util.Date; ...

  3. Rhythmk 学习 Hibernate 06 - Hibernate 表间关系 [One To One]

    1.One To One 单相 背景: 古代一个老婆  只能关联一个老公 husband.java package com.rhythmk.model; public class husband { ...

  4. 学习ORM框架—hibernate(三):跟踪持久化对象状态,掌握对象持久化

    准备工作 在上篇博客中学习ORM框架—hibernate(一):初识hibernate,通过简单的实例说明O和R的映射过程.本篇博客将要介绍hibernate中持久化对象的状态,并使用hibernat ...

  5. Hibernate 系列 02 - Hibernate介绍及其环境搭建

    引导目录: Hibernate 系列教程 目录 昨晚喝多了,下午刚清醒,继续搞Hibernate.走起. 觉得还行的话,记得点赞哈,给我这个渣渣点学习的动力.有错误的话也请指出,省的我在错误上走了不归 ...

  6. [原创]java WEB学习笔记77:Hibernate学习之路---Hibernate 版本 helloword 与 解析,.环境搭建,hibernate.cfg.xml文件及参数说明,持久化类,对象-关系映射文件.hbm.xml,Hibernate API (Configuration 类,SessionFactory 接口,Session 接口,Transaction(事务))

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  7. Hibernate学习一:Hibernate注解CascadeType

    http://zy19982004.iteye.com/blog/1721846 ———————————————————————————————————————————————————————— Hi ...

  8. hibernate学习系列-----(3)Session 缓存和持久化生命周期以及Session 基本操作

    Session缓存原理 为了能够在控制台更好的看到我们的hibernate干了些什么,可以在hibernate.cfg.xml文件中写入如下配置: <!-- print all generate ...

  9. 【SSH之旅】一步步学习Hibernate框架(一):关于持久化

    在不引用不论什么框架下,我们会通过平庸的代码不停的对数据库进行操作,产生了非常多冗余的可是又有规律的底层代码,这样频繁的操作数据库和大量的底层代码的反复书写极大的浪费了程序人员的书写.就在这样一种情况 ...

随机推荐

  1. gitlab访问限制问题------Forbidden

    解决方案: cd /etc/gitlab vim /gitlab.rb gitlab_rails['rack_attack_git_basic_auth'] = { 'enabled' => t ...

  2. hdu2149巴什博弈输出

    一眼就能看出来的巴什博弈,只是要输出第一步取的值,如果m>n+1,输出m%(n+1),否则输出m到n,因为这是第一步 #include<map> #include<set> ...

  3. voj 1406 floyd

    传说,上古时期的某个七月七日,王母娘娘为了阻止牛郎织女的爱情,划一道玉钗拆散鸳鸯,使两人“星桥鹊驾,经年才见,想离情.别恨难穷.”于是,“执子之手,与子偕老”成了天下有情人共同的希翼. 在气宇轩昂.玉 ...

  4. [转载]ORACLE EXP/IMP

    转载自:https://www.cnblogs.com/mengfanrong/p/3792955.html 本文对Oracle数据的导入导出 imp ,exp 两个命令进行了介绍, 并对其对应的參数 ...

  5. ASPX 后台调用前台Js

    1.UpdatePanel 使用中 protected void Button1_Click(object sender, EventArgs e) { this.Label1.Text = &quo ...

  6. 在JavaScript中进行文件处理,第一部分:基础

    译注:原文是<JavaScript高级程序设计>的作者Nicholas Zakas写的,本翻译纯属为自己学习而做,仅供参考.原文链接:这里 很多年前,我在一次Goole面试被问到,如何在w ...

  7. Monkey测试准备工作

    1.下载Android SDK 2.打开SDK Manager.exe自动下载 3.配置环境变量 将platform-tools的路径(如: C:\001myWorkspace\eclipse(MAV ...

  8. PyalgoTrade 计算权重平滑平均价(三)

    本节介绍如何使用收盘价的SMA价格的策略 from pyalgotrade import strategy from pyalgotrade.barfeed import yahoofeed from ...

  9. wpf 客户端【JDAgent桌面助手】开发详解(一)主窗口 圆形菜单

    目录区域: wpf 客户端[JDAgent桌面助手]业余开发的终于完工了..晒晒截图wpf 客户端[JDAgent桌面助手]开发详解-开篇 内容区域: 这里开始主窗口 圆形菜单制作的过程,首先请大家看 ...

  10. Linux中的中断处理

    1. Linux中中断除了中断分层之外,还有一种就是中断线程化 存在意义:在Linux中,中断具有最高的优先级.不论在任何时刻,只要产生中断事件,内核将立即执行相应的中断处理程序,等到所有挂起的中断和 ...