二、状态转化方法

前面说到对象之间的转化过程是通过使用方法来实现的,这些方法是很重要的,先看张图

上面这张图在三篇文章中都有用到,它详细描述了持久对象三种状态的转换过程及具体的转化方法,另外还有垃圾回收器,对象在瞬态和脱管状态下如果长时间不适用将会在某一时刻被Java回收器回收,消亡。

1、对象直接进入Persistent状态

1.1 get方法

从数据库中获取一行信息,并将该信息同步到创建的对象中,该方法返回一个Object对象,如果没有查询到内容则返回null。下面的实例通过采用Session的get方法来获取一个对象,并将对象转换为实例。

[java] view plaincopy
  1. public void testGet1(){
  2. Session session=null;
  3. Transaction tx = null;
  4. try{
  5. session=HibernateUtils.getSession();
  6. //开启事务
  7. tx= session.beginTransaction();
  8. //get加载上来的对象为持久对象
  9. //执行get会马上发出查询语句,如果不存在会返回null
  10. User user=(User)session.get(User.class,"ff80808145bc28cc0145bc28ce020002");
  11. System.out.println(user.getName());
  12. //persistent状态
  13. //persistent状态的对象,当对象的属性发生改变的时候
  14. //Hibernate在清理缓存(脏数据检查)的时候,会和数据库同步
  15. user.setName("赵柳");
  16. session.getTransaction().commit();
  17. }catch(Exception e){
  18. e.printStackTrace();
  19. if(tx != null){
  20. tx.rollback();
  21. }
  22. }finally{
  23. HibernateUtils.closeSession(session);
  24. }
  25. }

设置断点,获取User对象。

获取到了该对象,通过强制转换后得到了一个user对象。程序中添加了setName方法,也就是说会更新数据库中的名称,执行完成后检查数据库,如下图更新结果。                        

1.2 load方法

功能类似于get方法,也是从数据库中获取数据并同步到对象中,该方法支持lazy是一种懒汉操作,它返回的是一个持久化的Object对象或者一个代理,所以需要进行转化。

[java] view plaincopy
  1. public void testLoad1(){
  2. Session session=null;
  3. try{
  4. session=HibernateUtils.getSession();
  5. //不会马上查询语句,因为load支持lazy(延迟加载/懒加载)
  6. //什么教lazy?只有真正使用这个对象的时候,再创建,对于Hibernate来说
  7. //才真正发出查询语句,主要为了提高性能,lazy是Hibernate中非常重要的特性
  8. //Hibernate的lazy是如何实现的?采用代理对象实现,代理对象主要采用的是CGLIB库生成的
  9. //而不是JDK的动态代理,因为JDK的动态代理只能对实现了借口的类生成代理,CGLIB可以对类生成
  10. //代理,它采用的是继承方式
  11. User user=(User)session.load(User.class,"8a1b653745bcc7b50145bcc7b7140001");
  12. System.out.println(user.getName());
  13. //persistent状态
  14. //persistent状态的对象,当对象的属性发生改变的时候
  15. //Hibernate在清理缓存(脏数据检查)的时候,会和数据库同步
  16. user.setName("zhaoliu");
  17. session.getTransaction().commit();
  18. }catch(Exception e){
  19. e.printStackTrace();
  20. }finally{
  21. HibernateUtils.closeSession(session);
  22. }
  23. }

查询获取该User对象如下图:


        分析上图,获取的User对象并不完整,或者说并没有常见一个User对象,更是一种代理,它使用了CGLIB来预加载对象,只有在使用该对象时才真正创建。

1.3 Get Vs load

get和load方法很重要,在面试Hibernate时经常会考到,下面对比下两者。
       相同点:(1)功能相同,将关系数据转化为对象;

(2)使用方法相同,同样需要制定两个参数
       不同点:(1)load方法支持lazy操作,预加载对象,在使用时才创建,get是直接将关系数据转化为对象;

(2)load加载对象如果不存在会抛出objectNotFoundException异常,get如果没有获取数据会返回null。

2、手动构造detached对象

想要获取对象还有另外一种方法,它区别于get与load方法,是一种手动获取的方法,首先常见一个对象,然后通过制定id的方式获取该对象的数据,方法如下:

[java] view plaincopy
  1. public void testUer(){
  2. Session session=null;
  3. try{
  4. session=HibernateUtils.getSession();
  5. session.beginTransaction();
  6. //手动构造detached对象
  7. User user=new User();
  8. user.setId("8a1b653745bcc7b50145bcc7b7140001");
  9. //persistent状态
  10. //persistent状态的对象,当对象的属性发生改变的时候
  11. //Hibernate在清理缓存(脏数据检查)的时候,会和数据库同步
  12. session.getTransaction().commit();
  13. }catch(Exception e){
  14. e.printStackTrace();
  15. }finally{
  16. HibernateUtils.closeSession(session);
  17. }
  18. }

查看获取的结果图:


                    
       分析结果图,代码中使用了setId方法为该对象制定了id号,在制定id号后就能够对该对象进行操作,在事务提交后同步到数据库中,采用了手动指定,手动指定了对象的信息。

2.1 Delete方法

删除数据库中指定的对象,在删除前必须将对象转化到Persistent状态,可以使用get、load或者手动的方法指定对象,使用方法如下代码:

[java] view plaincopy
  1. session=HibernateUtils.getSession();
  2. session.beginTransaction();
  3. User user=(User)session.load(User.class,"8a1b653745bcc6d50145bcc6d67a0001");
  4. //建议采用此种方式删除,先加载再删除
  5. session.delete(user);

2.2 Update

更新数据,该方法会修改数据库中的数据。在使用的时候会出现量中情况,更新数据库某个字段值或者更新数据库的整行值

2.2.1  更新某个字段值

如果只想要更新某个字段的值,在update前,需要使用load或者get方法使对象转化为persistent状态代码如下:

[java] view plaincopy
  1. //获取session对象
  2. session=HibernateUtils.getSession();
  3. //开启事务
  4. session.beginTransaction();
  5. //或者可以使用另外的方法开启
  6. //session.getTransaction().begin();
  7. //加载获取User对象
  8. //方法一:使用load方法
  9. //User user=(User)session.load(User.class, "8a1b653745bcc7b50145bcc7b7140001");
  10. //方法二:手动获取
  11. User user=new User();
  12. user.setId("8a1b653745bcc7b50145bcc7b7140001");
  13. //更新姓名
  14. user.setName("zhangsan");
  15. session.update(user);
  16. session.getTransaction().commit();

2.2.2 更新整行

想要更新整行的数据,可以采用手动将状态转换到detached状态,手动指定对象的id值,代码如下:

[java] view plaincopy
  1. //获取session对象
  2. session=HibernateUtils.getSession();
  3. //开启事务
  4. session.beginTransaction();
  5. //或者可以使用另外的方法开启
  6. //session.getTransaction().begin();
  7. //手动获取
  8. User user=new User();
  9. user.setId("8a1b653745bcc7b50145bcc7b7140001");
  10. //更新姓名
  11. user.setName("zhangsan");
  12. session.update(user);
  13. session.getTransaction().commit();

查看更新结果:


      分析更新结果,它其实更新了数据库的整行数据,这种更新操作有太多的不确定因素,不建议使用。

2.3 save方法

插入数据。在执行save方法时会调用数据库的insert语句,向数据库中添加新的一行。save后的对象会转化为持久态,在此状态下的对象能够再次更新对象,在最后提交事务时会同更改更新到数据库。如下:

[java] view plaincopy
  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. tx.commit();
  20. }catch(Exception e){
  21. e.printStackTrace();
  22. if(tx != null){
  23. tx.rollback();
  24. }
  25. }finally{
  26. HibernateUtils.closeSession(session);
  27. }
  28. //detached状态
  29. }

查看上例运行结果视图:


        分析结果:session在提交事务的时候其实做了两部的操作,结合代码中的更新过程,首先是新增了一个User对象,之后执行了save操作,它会调用insert语句,然后在代码中做了一个setName的操作,重新修改了名称,但这时还没有同步到数据库中而是在内存中,这时就会有两种状态,我们称此时的数据位脏数据,最后提交事务的时候更新到数据库中。

结语

本文针对持久对象的转化方法展开了详细的讨论,一个对象在整个生命周期中有三种状态。文章讨论至此,核心对象和持久对象的讨论已经完成,核心对象构成了Hibernate的内部运行机制,持久对象是关系模型和对象模型进行转化的核心。

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

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

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

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

    一.状态解析       Hibernate的持久对象主要分为三个状态,Transient.Persistent.Detached,其中Transient称为瞬态,没有被数据库管理,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. vue-cli脚手架(框架)
  2. C++多继承(多重继承)详解(一)
  3. css垂直居中技巧总结
  4. Java魔法堂:URI、URL(含URL Protocol Handler)和URN
  5. Linux服务器硬盘更换,[ Linux ] 服务器更换硬盘
  6. 数据可视化最容易被人忽略的四大误区,怪不得我的报告总被老板骂
  7. 线性表:链式队列算法实现
  8. JavaScript(二)—— JavaScript 运算符/JavaScript 流程控制/JavaScript 数组
  9. iOS WebView生成长截图的第三种解决方案
  10. 商城app源码_多商户商城源码系统有什么优势呢?
  11. python同花顺交易接口_TradeApi为A股程序化交易接口2.9.0发布
  12. html遮罩层动画制作,教你用Flash遮罩层制作漂亮的文字效果
  13. 最新版gg服务器框架安装器,GG服务框架安装器
  14. 四、s3c2440 裸机开发 通用异步收发器UARN
  15. 原来等待我做的事情还有很多
  16. HC-SR501人体红外感应模块程序
  17. 宏观经济学gdp计算方法_宏观经济学GDP中存货是怎么算的,能说一下吗
  18. 罗永浩二次直播遇冷,用户到底想要什么样的直播 ?
  19. 怎样在手机上弄电子版文档_如何在手机上把word转成pdf?
  20. 使用vue插件实现全球地图,实现你环游世界的梦

热门文章

  1. anaconda 包区别 版本_我是如何用Anaconda来管理Python的
  2. 在WCF中启用事务的6个步骤
  3. 将ONNX对象检测模型转换为iOS Core ML(一)
  4. 深度操作系统 Deepin 15.11 发布
  5. 无法连接iphone软件更新服务器_上海腾科教育今日分享——提示“无法连接到服务器”的解决办法...
  6. pythonwin是什么_winpython是什么
  7. vue 设置每个页面的title
  8. mysql内外三种连接_mysql之内连接,外连接(左连接,右连接),union,union all的区别...
  9. 怎么用计算机求浮动额,2015计算机一级考试MSOFFICE上机综合训练(5)
  10. python构造数组并命名_Numpy数组追加命名列