文档章节

Rhythmk 学习 Hibernate 02 - Hibernate 之 瞬时状态 离线状态 持久化状态 三状态

rhythmk
 rhythmk
发布于 2014/08/16 16:37
字数 949
阅读 13
收藏 0

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
粉丝 1
博文 62
码字总数 40987
作品 0
广州
私信 提问
深入hibernate的三种状态

学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别,比如瞬时状态就是刚new出来一...

刘梓航
2014/11/04
100
0
深入hibernate的三种状态

学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别,比如瞬时状态就是刚new出来一...

happy圈圈
2015/03/25
109
0
Hibernate-ORM:06.Hibernate中三种状态

------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客主要叙述Hibernate中的三种状态:临时状态(瞬时状态),持久状态,游离状态 commit和flush三种状态间的使用,com...

晨曦dawn
2018/05/28
0
0
Hibernate对象三状态(state)

Hibernate对象三状态(state): 瞬时(Transient) - 由操作符创建,且尚未与Hibernate 关联的对象被认定为瞬时(Transient)的。瞬时(Transient)对象不会被持久化到数据库中,也不会被赋予持久化标...

小湘西
2016/09/19
17
0
Hibernate杂问

1 谈谈你对ORM框架的基本思想的了解? 首先 ORM是 对象关系映射,是为了解决类似于JDBC实现对象持久化的问题开发的。 框架的基本特征:完成面向对象的编程语言到关系数据库之间的映射。 他的...

陈嘻嘻哈哈
2015/12/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

nginx+tomcat配置https

1、nginx配置https和【proxy_set_header X-Forwarded-Proto $scheme;】 2、java代码: String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServe......

perofu
24分钟前
4
0
必看的Linux系统新手进阶老手心得

不知道从什么时候起,linux这个话题变得越来越普及,成为大家经常讨论的话题。无论在网络上还是实际生活中,竟然很多人都在纠结学习linux的问题。网络上给的答案千千万万,而却还有很多人踌躇...

Linux就该这么学
27分钟前
4
0
Spring Boot 配置元数据指南

1. 概览 在编写 Spring Boot 应用程序时,将配置属性映射到 Java bean 上是非常有用的。但是,记录这些属性的最好方法是什么呢? 在本教程中,我们将探讨 Spring Boot Configuration Proces...

liululee
30分钟前
3
0
foreach查找子类

$list = $menu_model -> menu_list();$parent_list = [];foreach ($list as $v){ if ($v['pid'] == 0) { $parent = $v; foreach ($list as $v1) ......

小小小壮
42分钟前
3
0
基于 HTML5 Canvas 实现的 TP-LINK 电信拓扑设备面板

前言 今天我们以真实的 TP-LINK 设备面板为模型,完成设备面板的搭建,和指示灯的闪烁和图元流动。 先来目睹下最终的实现效果:http://www.hightopo.com/demo/blog_tplink_20170511/index.h...

htdaydayup
48分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部