【Hibernate步步为营】--核心对象+持久对象全析(三)
上篇文章讨论了Hibernate持久对象的生命周期,在整个生命周期中一个对象会经历三个状态,三种状态的转换过程在开发过程中是可控的。并且是通过用法来控制它们的转化过程。详细的转化过程今天就来着重讨论下。
二、状态转化方法
前面说到对象之间的转化过程是通过用法来实现的,这些方法是非常重要的。先看张图
上面这张图在三篇文章中都实用到,它具体描写叙述了持久对象三种状态的转换过程及具体的转化方法。另外还有垃圾回收器,对象在瞬态和脱管状态下假设长时间不适用将会在某一时刻被Java回收器回收,消亡。
1、对象直接进入Persistent状态
1.1 get方法
从数据库中获取一行信息。并将该信息同步到创建的对象中,该方法返回一个Object对象,假设没有查询到内容则返回null。以下的实例通过採用Session的get方法来获取一个对象。并将对象转换为实例。
public void testGet1(){
Session session=null;
Transaction tx = null;
try{
session=HibernateUtils.getSession();
//开启事务
tx= session.beginTransaction();
//get载入上来的对象为持久对象
//运行get会立即发出查询语句。假设不存在会返回null
User user=(User)session.get(User.class,"ff80808145bc28cc0145bc28ce020002");
System.out.println(user.getName());
//persistent状态
//persistent状态的对象,当对象的属性发生改变的时候
//Hibernate在清理缓存(脏数据检查)的时候,会和数据库同步
user.setName("赵柳");
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
if(tx != null){
tx.rollback();
}
}finally{
HibernateUtils.closeSession(session);
}
}
设置断点。获取User对象。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmdfeGlueGl1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
获取到了该对象,通过强制转换后得到了一个user对象。程序中加入了setName方法,也就是说会更新数据库中的名称。运行完毕后检查数据库,例如以下图更新结果。
1.2 load方法
功能类似于get方法,也是从数据库中获取数据并同步到对象中,该方法支持lazy是一种懒汉操作,它返回的是一个持久化的Object对象或者一个代理,所以须要进行转化。
public void testLoad1(){
Session session=null;
try{
session=HibernateUtils.getSession();
//不会立即查询语句,由于load支持lazy(延迟载入/懒载入)
//什么教lazy?仅仅有真正使用这个对象的时候。再创建,对于Hibernate来说
//才真正发出查询语句,主要为了提高性能,lazy是Hibernate中很重要的特性
//Hibernate的lazy是怎样实现的?採用代理对象实现。代理对象主要採用的是CGLIB库生成的
//而不是JDK的动态代理。由于JDK的动态代理仅仅能对实现了借口的类生成代理,CGLIB能够对类生成
//代理。它採用的是继承方式
User user=(User)session.load(User.class,"8a1b653745bcc7b50145bcc7b7140001");
System.out.println(user.getName());
//persistent状态
//persistent状态的对象,当对象的属性发生改变的时候
//Hibernate在清理缓存(脏数据检查)的时候。会和数据库同步
user.setName("zhaoliu");
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
}finally{
HibernateUtils.closeSession(session);
}
}
查询获取该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的方式获取该对象的数据。方法例如以下:
public void testUer(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction();
//手动构造detached对象
User user=new User();
user.setId("8a1b653745bcc7b50145bcc7b7140001");
//persistent状态
//persistent状态的对象,当对象的属性发生改变的时候
//Hibernate在清理缓存(脏数据检查)的时候。会和数据库同步
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
}finally{
HibernateUtils.closeSession(session);
}
}
查看获取的结果图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmdfeGlueGl1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
分析结果图,代码中使用了setId方法为该对象制定了id号。在制定id号后就行对该对象进行操作,在事务提交后同步到数据库中,採用了手动指定,手动指定了对象的信息。
2.1 Delete方法
删除数据库中指定的对象,在删除前必须将对象转化到Persistent状态,能够使用get、load或者手动的方法指定对象,用法例如以下代码:
session=HibernateUtils.getSession();
session.beginTransaction();
User user=(User)session.load(User.class,"8a1b653745bcc6d50145bcc6d67a0001");
//建议採用此种方式删除,先载入再删除
session.delete(user);
2.2 Update
更新数据。该方法会改动数据库中的数据。在使用的时候会出现量中情况。更新数据库某个字段值或者更新数据库的整行值
2.2.1 更新某个字段值
假设仅仅想要更新某个字段的值,在update前。须要使用load或者get方法使对象转化为persistent状态代码例如以下:
//获取session对象
session=HibernateUtils.getSession();
//开启事务
session.beginTransaction();
//或者能够使用另外的方法开启
//session.getTransaction().begin(); //载入获取User对象
//方法一:使用load方法
//User user=(User)session.load(User.class, "8a1b653745bcc7b50145bcc7b7140001");
//方法二:手动获取
User user=new User();
user.setId("8a1b653745bcc7b50145bcc7b7140001"); //更新姓名
user.setName("zhangsan");
session.update(user);
session.getTransaction().commit();
2.2.2 更新整行
想要更新整行的数据,能够採用手动将状态转换到detached状态。手动指定对象的id值,代码例如以下:
//获取session对象
session=HibernateUtils.getSession();
//开启事务
session.beginTransaction();
//或者能够使用另外的方法开启
//session.getTransaction().begin(); //手动获取
User user=new User();
user.setId("8a1b653745bcc7b50145bcc7b7140001"); //更新姓名
user.setName("zhangsan");
session.update(user);
session.getTransaction().commit();
查看更新结果:
分析更新结果,它事实上更新了数据库的整行数据,这样的更新操作有太多的不确定因素,不建议使用。
2.3 save方法
插入数据。
在运行save方法时会调用数据库的insert语句,向数据库中加入新的一行。save后的对象会转化为持久态,在此状态下的对象可以再次更新对象,在最后提交事务时会同更改更新到数据库。例如以下:
public void testSave2(){
Session session=null;
Transaction tx = null;
try{
session=HibernateUtils.getSession();
//开启事务
tx= session.beginTransaction();
//Transient状态
User user=new User();
user.setName("zhangsi");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
//persistent状态
//persistent状态的对象。当对象的属性发生改变的时候
//Hibernate在清理缓存(脏数据检查)的时候。会和数据库同步
session.save(user);
user.setName("lisi");
tx.commit();
}catch(Exception e){
e.printStackTrace();
if(tx != null){
tx.rollback();
}
}finally{
HibernateUtils.closeSession(session);
}
//detached状态
}
查看上例执行结果视图:
分析结果:session在提交事务的时候事实上做了两部的操作,结合代码中的更新过程,首先是新增了一个User对象,之后运行了save操作,它会调用insert语句。然后在代码中做了一个setName的操作,又一次改动了名称。但这时还没有同步到数据库中而是在内存中。这时就会有两种状态。我们称此时的数据位脏数据,最后提交事务的时候更新到数据库中。
结语
本文针对持久对象的转化方法展开了具体的讨论。一个对象在整个生命周期中有三种状态。文章讨论至此。核心对象和持久对象的讨论已经完毕。核心对象构成了Hibernate的内部执行机制,持久对象是关系模型和对象模型进行转化的核心。
【Hibernate步步为营】--核心对象+持久对象全析(三)的更多相关文章
- 【Hibernate步步为营】--核心对象+持久对象全析(一)
引言 上篇博客对Hibernate进行了基本的解析.并分析了它的一些特性. Hibernate可以如此的流行也是由于它有诸多长处,不论什么事物都有两面性.Hibernate尽管流行.可 ...
- 【Hibernate步步为营】--核心对象+持久对象全析(二)
上篇文章讨论了Hibernate的核心对象,在开发过程中经经常使用到的有JTA.SessionFactory.Session.JDBC,当中SessionFactory可以看做数据库的镜像,使用它可以 ...
- Hibernate的核心对象关系映射
Hibernate的核心就是对象关系映射: 加载映射文件的两种方式: 第一种:<mapping resource="com/bie/lesson02/crud/po/employee. ...
- hibernate在持久对象的生命周期(三州:自由状态,持久状态,自由状态 之间的转换)
三种状态的基本概念: 1. 临时身份(Transient):也被称为自由状态,它只存在于内存中,并且在数据库中没有相应的数据. 使用new创建的对象,久化,没有处于Session中,处于此状态的对象 ...
- Hibernate入门(3)- 持久对象的生命周期介绍
在hibernate中对象有三种状态:瞬时态(Transient). 持久态(Persistent).脱管态或游离态(Detached).处于持久态的对象也称为PO(Persistence Objec ...
- Hibernate(开放源代码的对象关系映射框架)
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自 ...
- JavaEE之Hibernate(开放源代码的对象关系映射框架)
Hibernate(开放源代码的对象关系映射框架) 1.简介 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全 ...
- Hibernate一级缓存Session和对象的状态
建议看原文:https://blog.csdn.net/qq_42402854/article/details/81461496 一.session简介 首先,SessionFactor ...
- Hibernate的session缓存和对象的四种状态
一.session缓存 说session缓存就得说到JAVA对象的生命周期,当没有任何引用指向一个对象时,对象则可以被gc回收,也就是生命周期结束了 而hibernate获取一个对象后,会将对象存入s ...
随机推荐
- .net SignalR 聊天室
代码地址:https://gitee.com/srnsrn/netSignalr.git 运行项目打开多个页面 私密聊天
- 【bzoj1907】树的路径覆盖 树形dp
题目描述 输入 输出 样例输入 1 7 1 2 2 3 2 4 4 6 5 6 6 7 样例输出 3 题解 树形dp 设f[x]表示以x为根的子树完成路径覆盖,且x为某条路径的一端(可以向上延伸)的最 ...
- ACM程序设计选修课——1041: XX's easy problem(神烦的多次字符串重定向处理)
1041: XX's easy problem Time Limit: 1 Sec Memory Limit: 128 MB Submit: 41 Solved: 7 [Submit][Statu ...
- HDU——1397Goldbach's Conjecture(二分查找+素数打表)
Goldbach's Conjecture Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...
- [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机)
[LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机) 试题描述 IOI 的比赛开始了.Jsp 和 Rlc 坐在一个角落,这时他们听到了一个异样的声音 …… 接着他们发现自己收 ...
- C# 数据库写入Sql Bulk索引损坏异常问题System.InvalidOperationException: DataTable internal index is corrupted: '4'
C# 数据库写入Sql Bulk索引损坏异常问题 System.InvalidOperationException: DataTable internal index is corrupted: '4 ...
- c语言第二题
在我们的业务中经常会遇到很多业务,字符串会有一系列的操作,请写出以下的方法 1.写一个函数,给定char *p,char q,判断char *p中是否包含char q这个字符,包含则返回这个字符的下标 ...
- 几个类和Table的方法
public class TableHelper { public static DataTable CreateTableFromClass(Type t) { DataTable dt = new ...
- Android组件实例化问题
对于Application. Activity. Notification. BroadCast. Service 这些组件的使用,对象的实例化问题各有不同,如何实例化以及在什么时候实例化也所有不同. ...
- The disk contains an unclean file system
Ubuntu : Status 14: The disk contains an unclean file system By mkyong | July 23, 2014 | Viewed : 10 ...