一、状态解析

      Hibernate的持久对象主要分为三个状态,Transient、Persistent、Detached,其中Transient称为瞬态,没有被数据库管理,Hibernate没有为对象分配id,在数据库中没有对应的行,一般在new出一个对象后转化为瞬态;Persistent称为持久化,此时已经被Session管理,Hibernate为对象分配了一个id(该id可以使用其它方法手动或者自动分配,id的类型可以在User.hbm.xml中配置),在数据库中已经有了对应的一行,在调用session的save方法后会提交到数据库中;Detached称为脱管对象,此时已经将修改同步到了数据库中,它有Hibernate分配的id,但是此时的id是在持久化状态分配的,在编程时此状态的对象往往已经不受session管理,如果想要再次修改可以再次创建一个session,然后管理对象。Transient、Detached的对象如果长时间不使用的话,会在某一时间段被Java的垃圾回收装置进行回收。

1、Transient:数据库中没有,没有被Session管理


       从Hibernate的体系结构图中不难看出,对象的瞬态是在应用程序中完成的,当对象被创建后即转变为瞬态,它还没有持久化的过程,也就是说并没有持久化标示(id号,Hibernate在创建持久化对象时都会为该对象指定一个id标示,保证唯一性)。瞬态的对象如果没有任何的操作的话,会在某一时刻消亡,并被Java的垃圾回收器回收。

事例演示:在SessionTest中添加一个名为testSave1的方法,代码如下:

  1. public void testSave1(){
  2. Session session=null;
  3. Transaction tx = null;
  4. try{
  5. session=HibernateUtils.getSession();
  6. //开启事务
  7. tx= session.beginTransaction();
  8. //Transient状态
  9. User user=new User();
  10. user.setName("zhangsi");
  11. user.setPassword("123");
  12. user.setCreateTime(new Date());
  13. user.setExpireTime(new Date());
  14. }catch(Exception e){
  15. e.printStackTrace();
  16. if(tx != null){
  17. tx.rollback();
  18. }
  19. }finally{
  20. HibernateUtils.closeSession(session);
  21. }
  22. //detached状态
  23. }

在save方法处设置断点,运行调试,输出结果如下图:

   

2、Persistent:数据库中有,被session管理


        一个瞬态的对象操作完成后需要保存操作,这时候调用save或者其他保存方法时即被转换为持久对象,这时候Hibernate给该对象创建一个持久化标示,并且可能在数据库中有了一个对应行,而且该标示与Java标示(该值表示对象在内存的位置)等价。
       另外一个没有被创建的对象同样可以使用其它的方法来直接转换到该状态,如上图的get、load等方法。persistent状态的对象若发生了改变,则在清理内存时或者在脏数据检查时会把改变同步到数据库中,那么此时会生成两条语句,分别为insert和update。在SessionTest中添加saveTest2方法,测试持久态

  1. public void testSave2(){
  2. Session session=null;
  3. Transaction tx = null;
  4. try{
  5. session=HibernateUtils.getSession();
  6. //开启事务
  7. tx= session.beginTransaction();
  8. //Transient状态
  9. User user=new User();
  10. user.setName("zhangsi");
  11. user.setPassword("123");
  12. user.setCreateTime(new Date());
  13. user.setExpireTime(new Date());
  14. //persistent状态
  15. //persistent状态的对象,当对象的属性发生改变的时候
  16. //Hibernate在清理缓存(脏数据检查)的时候,会和数据库同步
  17. session.save(user);
  18. user.setName("lisi");
  19. //可以显示的调用udpdate方法,因为此时为持久状态,调用udpate没有什么意义
  20. session.update(user);
  21. tx.commit();
  22. }catch(Exception e){
  23. e.printStackTrace();
  24. if(tx != null){
  25. tx.rollback();
  26. }
  27. }finally{
  28. HibernateUtils.closeSession(session);
  29. }
[java] view plaincopy
  1. }

调用save方法后进入的持久态,此时的为user对象添加了id标识:

        方法执行完成后会向数据库中添加新的一条信息,细心的童鞋可以看出方法中调用了两次setName方法,最后结果是什么呢,查看mysql中的表可以看到:

数据库中添加的最后信息是lisi,所以它最后执行了更新操作,此时在控制台中会打印两条sql语句,分别为insert和update语句。
      Note:在提交事务或者关闭Session前,会调用Session的flush方法对每个更改进行操作。

3、Detached:数据库中有,没有被session管理


       脱管状态下的对象其实已经被映射到了数据库中,只不过此时还没有被垃圾回收期回收,此时的对象拥有持久化标识,该标识对应着数据库中的一行,但是不保证该标识与Java标识对应。
       在SessionTest类中添加testSave3方法,测试Detached状态下对象和数据库,代码如下:
  1. public void testSave3(){
  2. Session session=null;
  3. Transaction tx = null;
  4. User user=null;
  5. try{
  6. session=HibernateUtils.getSession();
  7. //开启事务
  8. tx= session.beginTransaction();
  9. //Transient状态
  10. user=new User();
  11. user.setName("zhangsi");
  12. user.setPassword("123");
  13. user.setCreateTime(new Date());
  14. user.setExpireTime(new Date());
  15. //persistent状态
  16. //persistent状态的对象,当对象的属性发生改变的时候
  17. //Hibernate在清理缓存(脏数据检查)的时候,会和数据库同步
  18. session.save(user);
  19. user.setName("lisi");
  20. tx.commit();
  21. }catch(Exception e){
  22. e.printStackTrace();
  23. if(tx != null){
  24. tx.rollback();
  25. }
  26. }finally{
  27. HibernateUtils.closeSession(session);
  28. }
  29. //detached状态
  30. user.setName("wangwu");
  31. try{
  32. session=HibernateUtils.getSession();
  33. session.beginTransaction();
  34. //将detached状态的对象重新纳入session管理
  35. //此时将变为persistent状态的对象
  36. //persistent状态的对象,在清理缓存时会和数据库同步
  37. session.update(user);
  38. session.getTransaction().commit();
  39. }catch(Exception e){
  40. e.printStackTrace();
  41. session.getTransaction().rollback();
  42. }finally{
  43. HibernateUtils.closeSession(session);
  44. }
  45. }

执行完成后,查看数据库中信息,如下图:

分析执行结果,不难发现它最后完成的是更新操作,不同的是detached状态下的对象必须重新定义新的Session对象,因为Session对象线程不安全,容易出错。

结语

       上文主要讨论分析了Hibernate持久对象在整个声明周期的状态转化过程,这几种状态的相互转化使得关系模型和对象模型进行了紧密的关联,另外在使用配置文件来管理这几种状态,这样使得Hibernate的操作简单,并且功能强大。上文只是针对持久对象的几种状态做了初步的解析,另外还有状态之间的转化方法将会在下篇文章讨论。

核心对象+持久对象全析(2)相关推荐

  1. 核心对象+持久对象全析(3)

    二.状态转化方法 前面说到对象之间的转化过程是通过使用方法来实现的,这些方法是很重要的,先看张图 上面这张图在三篇文章中都有用到,它详细描述了持久对象三种状态的转换过程及具体的转化方法,另外还有垃圾回 ...

  2. 核心对象+持久对象全析(1)

    一.Hibernate核心 1.核心解析图 一个非常简单的Hibernate体系结构图: 从上图可以看出,Hibernate使用数据库和配置信息来为应用程序提供持久化服务.应用程序创建的持久化对象收到 ...

  3. web核心 4-response响应对象 servletContext对象 响应行响应体 请求转发 重新定向 从服务器下载与上传资源 切换验证码 网站统计访问次数

    内容介绍 1 ServletContext对象2 response响应对象 ServletContext对象 概述 ServletContext:servlet的上下文对象(全局管理者) 一个项目有且 ...

  4. 从痴迷数据库SQL语句逐渐走进面向对象化(系统的核心以处理对象为主、淡化数据库概念)...

    几年前写信息管理系统都要设计很多很多表,每个表都是自己建立的,然后喜欢用高   性能.高超的SQL语句搞定很多复杂的商业逻辑问题,那SQL语句又长又复杂,一般人   还读不懂,但是代码很少.性能很高, ...

  5. wxWidgets:持久对象概述

    wxWidgets:持久对象概述 wxWidgets:持久对象概述 使用永久窗口 定义自定义持久化窗口 wxWidgets:持久对象概述 持久对象只是在销毁时自动保存状态并在重新创建时自动恢复状态的对 ...

  6. 【数据库系统】管理持久对象的模式

    持久对象的管理模式 持久对象的管理是应用程序设计的重要问题,解决好这个问题需要好的设计模式集合,如PEAA. 持久对象的管理模式主要有: 标识映射:给内存中的所有持久对象都指定OID,再将这些OID映 ...

  7. Jpa持久对象状态,一级缓存,二级缓存

    1JPA持久对象的状态 1.1. 临时状态(transient):瞬时状态 刚刚用new语句创建,没有和entityManager发生关系 没有被持久化,不处于entityManager中.该对象成为 ...

  8. 第八章 Caché 使用持久对象

    文章目录 第八章 Caché 使用持久对象 保存对象 回滚 保存对象和事务 测试保存对象的存在性 使用ObjectScript测试对象是否存在 使用SQL测试对象是否存在 打开保存的对象 多次调用%O ...

  9. JS对比两个对象键值全等

    比较两个对象的键值是否全等,说的就是字面上的相等,也就是看起来的一模一样的,举个栗子 let o1 = { let o2 = {name: 'joe', name: 'joe' isOld: fals ...

最新文章

  1. Apache commons-io
  2. OSI模型第四层传输层--TCP协议
  3. kafka reassign 限速_RabbitMQ 与 Kafka 的技术差异以及使用注意点
  4. P2579,jzoj2288-[ZJOI2005]沼泽鳄鱼【矩阵乘法】
  5. 基于JAVA+SpringMVC+Mybatis+MYSQL的网上零食销售系统
  6. SharePoint Portal Server之常见问题
  7. 串行通信(一):I2C
  8. Double得有效位
  9. CAD看图软件_CAD图纸管理软件
  10. gflags 调试内存_gflags 检查内存越界 | 学步园
  11. java null==null_Java中关于Null的9个解释(Java Null详解)
  12. mc服务器怎么回到床的位置,《我的世界》MC床的功能居然跟这四个指令有关系?很多人不知道!...
  13. java8中, 格林威治时间、世界时、祖鲁时间、GMT、UTC、跨时区、夏令时需要用什么类表示呢
  14. 由于找不到libmysql.dIl, 无法继续执行代码。重新安装程序可能会解决此问题
  15. 中国知网 万方 维普下载文献说明
  16. 第四章 专业统计(上)-统计实务
  17. vert.x笔记:4.vert.x中调用spring服务
  18. 2019 年开工福利
  19. 【演示工具】Focusky教程 | 添加“关于”信息
  20. 我有特殊的节能技巧,处理事件的时候我会装作四处看风景

热门文章

  1. python cos函数_Python Tensorflow cos()用法及代码示例
  2. Unity变量命名的6个重要提示
  3. (三)混合边缘AI人脸对齐
  4. PowerToys 0.19.0 发布,微软开发的免费实用工具集
  5. GaussDB(openGauss)宣布开源,性能超越 MySQL 与 PostgreSQL
  6. 准确率创新高,北大开源中文分词工具包 pkuseg
  7. linux hadoop namenode_HADOOP_HDFS伪分布式安装步骤
  8. 计算机网络管理2018版,2018~2019学年度第二学期“计算机网络管理”专业技能竞赛火热进行中...
  9. 单片机并口应用实验c语言,1单片机并口简单应用(流水灯).docx
  10. mysql数据库加载太慢_使用MySQL数据库很慢