Hibernate学习(4)- Hibernate对象的生命周期
1、Hibernate对象的生命周期(瞬时状态、持久化状态、游离状态)
1、瞬时状态(Transient):
使用new操作符初始化的对象就是瞬时状态,没有跟任何数据库数据相关联;
2、持久化状态(Parsistent):
如果对象与Session对象关联起来,且该对象对应到数据库记录,则称该对象处于持久化状态。
3、游离状态(Detached)
Session被关闭或调用了Session的evict或clear方法把它从Session中移除了,则该对象脱离了Session的管理,持久化状态变成游离状态,这表示该对象不在和数据库保持同步,不受hibernate管理。
2、三种状态的比较
Transient:瞬时状态的对象只存在于内存中。
Parsistent:持久状态的对象分别存在于内存、session对象、数据库之中。
Detached:游离状态的对象存在于内存、数据库之中,但不在session对象中。
3、三种状态之间的转换
1、转化路径详解
1)瞬时对象(Transient)
new 创建 (无->Transient) ,即:对象通过构造方法成为瞬时态;
2)持久对象(Persistent)
1.1)get/load (无->Persistent),即:对象可以由session的load或get方法直接成为持久态;
get通过类名和id从数据库读取指定记录,无匹配记录返回null。
load通过类名和id从数据库读取指定记录,无匹配记录抛ObjectNotException异常。
1.2)save/saveOrUpdate/persist (Transient->Persistent) ,即:瞬时态对象可以通过save,saveOrUpdate或persist方法成为持久态;
1.3)update/saveOrUpdate(Detached->Persistent),即:游离态对象则可以通过update,saveOrUpdate成为持久态;
3)游离对象(Detached)
游离态只能由持久态转换而来(Persistent->Detached),通过close、clear、evict方法实现。
evict--把某个对象从session中移除,变为游离态;
clear--把所有对象从session中移除,对象全部变为游离态;
close--关闭session,其中的对象全部变为游离态;
2、几种方法的详解
1、get 与 load
都是从数据库中加载数据封装为java对象,直接变为持久态;
2、save,update与saveOrUpdate
save是将瞬时态转为持久态;
update是将游离态转为持久态;
saveOrUpdate可以说是两者的综合,它执行时先判断对象的状态(主要是通过有无主键判断的),若是自由态,则save,若是游离态,则update;
3、save与persist
两者都是将对象由瞬时态转为持久态,但返回值不同:save返回主键值,而persist不返回;
4、实例,详见注解状态(封装的工具类详见Demo)
package com.demo.test; import org.hibernate.Session;
import org.junit.Test; import com.demo.Utils.HibernateUtil;
import com.demo.pojo.User; public class SessionTest { @Test
public void saveTest() {
Session session = null;
User user = null;
try {
session = HibernateUtil.currentSession();
session.beginTransaction();
//创建瞬时状态对象
user = new User();
user.setName("东方不败");
user.setPwd("123456");
//user仍是一个瞬态对象 //持久状态,user被session管理,并且id有值 -- oid
//此时user已变成 持久态对象
session.save(user); //在持久状态下脏数据检查:当提交事务,清理缓存时发现session中的数据与数据库的数据不一致时,会把session的数据更新到数据库
//保存以后,再修改对象,会产生多条sql语句,效率降低,所以在save前修改数据
user.setName("西方求败");
session.getTransaction().commit();
}catch (Exception e) {
e.printStackTrace();
}finally {
HibernateUtil.closeSession();
}
//close、clear、evict方法都会使持久态对象 变成 游离状态 -- user
user.setName("令狐冲"); try {
session = HibernateUtil.currentSession();
session.beginTransaction();
//update使对象变成 持久状态
session.update(user);
session.getTransaction().commit();
}catch (Exception e) {
e.printStackTrace();
}finally {
HibernateUtil.closeSession();
}
} @Test
public void getTest() {
Session session = null;
try {
session = HibernateUtil.currentSession();
//get后变为持久状态
//get方法会立即查询该对象:范围(查询不到去下一级查询)从session -> sessionFactory ->数据库
//get方法找不到对象,不会有异常,返回nul
User user = session.get(User.class, 7L);
System.out.println(user.toString()); User user2 = session.get(User.class, 17L);
System.out.println(user2);
}catch (Exception e) {
e.printStackTrace();
}finally {
HibernateUtil.closeSession();
}
} @Test
public void loadTest() {
Session session = null;
try {
session = HibernateUtil.currentSession();
//load后变为持久状态(这里加载机制与get不同,稍后我会单独写一篇文章 介绍 get与load 的区别)
//对象不存在时,抛出异常
User user = session.load(User.class, 7L);
System.out.println(user.toString()); User user2 = session.load(User.class, 17L);
System.out.println(user2.toString());
}catch (Exception e) {
e.printStackTrace();
}finally {
HibernateUtil.closeSession();
}
} @Test
public void clearTest() {
Session session = null;
User user = null;
try {
session = HibernateUtil.currentSession();
session.beginTransaction();
user = session.get(User.class,7L);
System.out.println(user.getName());
session.getTransaction().commit();
session.clear();
//游离状态,不被session管理,数据库不会被更改
user.setName("任我行");
System.out.println(user.getName());
}catch (Exception e) {
e.printStackTrace();
}finally {
HibernateUtil.closeSession();
}
} @Test
public void updateTest() {
Session session = null;
User user = null;
try {
session = HibernateUtil.currentSession();
session.beginTransaction();
//瞬时状态
//手动构造对象 也可以修改,但是需要指定所有的属性值,否则,不设置的对象会置空,不建议这样update数据
/*user = new User();
user.setId(7L);
user.setName("盈盈");
session.update(user);*/
//一般这样修改
//先去查询
user = session.get(User.class,7L);
if(user != null) {
user.setName("盈盈");
session.update(user);
}
session.getTransaction().commit();
}catch (Exception e) {
e.printStackTrace();
}finally {
HibernateUtil.closeSession();
}
} @Test
public void deleteTest() {
Session session = null;
User user = null;
try {
session = HibernateUtil.currentSession();
session.beginTransaction();
//瞬时状态
//手动构造一个对象,指定主键是可以删除数据的,不建议这样搞
/*user = new User();
user.setId(7L);
session.delete(user);*/
//应该这样删除数据
//从数据先加载该对象,然后删除,可以避免异常
user = session.get(User.class, 7L);
if(user != null) {
session.delete(user);
}
session.getTransaction().commit();
}catch (Exception e) {
e.printStackTrace();
}finally {
HibernateUtil.closeSession();
}
} }
PS:源码地址 https://github.com/JsonShare/hibernate-demo
PS:原文地址 http://www.cnblogs.com/JsonShare/p/8686078.html
Hibernate学习(4)- Hibernate对象的生命周期的更多相关文章
- java之hibernate之session中对象的生命周期
1. session是用来执行对象的crud操作,并且session是对象事务工厂.session是线程级别的,所以生命周期比较短. 2.session中对象的生命周期图: 3.session中对象的 ...
- [原创]java WEB学习笔记94:Hibernate学习之路---session 的管理,Session 对象的生命周期与本地线程绑定
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- hibernate 持久化对象的生命周期 2.1
持久化对象的生命周期 瞬态(自由态) 表示对象在内存中存在,在数据库中没有数据相关,比如刚刚new出来的一个对象 持久态 持久态指的是持久化对象处于由Hibernate管理的状态,这种状态下持久化对象 ...
- hibernate 持久化对象的生命周期
持久化对象的生命周期 瞬态(自由态) 表示对象在内存中存在,在数据库中没有数据相关,比如刚刚new出来的一个对象 持久态 持久态指的是持久化对象处于由Hibernate管理的状态,这种状态下持久化对象 ...
- Hibernate中Java对象的生命周期
一个对象的出生源于我们的一个new操作,当我们使用new语句创建一个对象,这个对象的生命周期就开始了,当我们不在有任何引用变量引用它,这个对象就的生命就此结束,它占用的内存就可以被JVM的垃圾回收器回 ...
- [原创]java WEB学习笔记81:Hibernate学习之路--- 对象关系映射文件(.hbm.xml):hibernate-mapping 节点,class节点,id节点(主键生成策略),property节点,在hibernate 中 java类型 与sql类型之间的对应关系,Java 时间和日期类型的映射,Java 大对象类型 的 映射 (了解),映射组成关系
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记47:Servlet 监听器简介, ServletContext(Application 对象), HttpSession (Session 对象), HttpServletRequest (request 对象) 监听器,利用listener理解 三个对象的生命周期
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- Hibernate学习笔记-Hibernate HQL查询
Session是持久层操作的基础,相当于JDBC中的Connection,通过Session会话来保存.更新.查找数据.session是Hibernate运作的中心,对象的生命周期.事务的管理.数据库 ...
- hibernate 学习 五 hibernate核心接口
一 Configuration接口 Configuration对象只存在于系统的初始化阶段.配置相关. 配置文件可以使用默认的路径,也可以指定路径. Configuration config = ne ...
随机推荐
- Axure使用心得分享
因为之前很少涉及到原型设计,所以对这个原型设计工具也不太熟悉,第一次使用走了不少的弯路,在这里把自己在使用过程中的心得跟大家分享一下,希望能够对大家有所帮助. 一. 元素的选择 我觉得这是Axure原 ...
- 极速搞定1小时不出结果SQL的优化(SQL Tuning)
今天帮用户做了一个SQL TUNING,原来为1个多小时不出结果,TUNING后为几秒,图片为我调优时参考的explain plan,隐去某些具体信息,虽然通过该计划,不能完全确定SQL慢的原因,但稍 ...
- EF6CodeFirst+MVC5+Autofac泛型注册 入门实例
贴一个EF6 CodeFirst模式结合MVC5和Autofac(泛型注册)的一个入门实例 网上类似的例子实在太少,最近自己也有用到这一块的知识,总结了一下,不要让后人踩了自己踩过的坑. 1:新建三个 ...
- SqlBulkCopy 批量复制数据到数据库
1.简介 1.MSDN 核心方法:SqlBulkCopy.WriteToServer 将所有行从数据源复制到 SqlBulkCopy 对象的 DestinationTableName 属性指定的目标表 ...
- python 生成器和迭代器有这篇就够了
本节主要记录一下列表生成式,生成器和迭代器的知识点 列表生成器 首先举个例子 现在有个需求,看列表 [0,1,2,3,4,5,6,7,8,9],要求你把列表里面的每个值加1,你怎么实现呢? 方法一(简 ...
- java保留小数点后位数以及输出反转数字
//方法一double b = 8.0/3.0; //与C语言不同,此处8.0和8有所区分 String format = String.format("%.2f,b"); //表 ...
- 搬瓦工搭建SS的教程
前言 作者写在前面的话: 应同学的要求在此分享搬瓦工搭建SS的教程,此教程只作为学习之用,因某些原因本教程不适合长期使用,在大家学习之后请删除所做的操作,谢谢. 为方便以后查看,请及时收藏:GitHu ...
- python中的小知识点
这里是一些小知识点的汇集,为的是以后查找的方便. 行与缩进: 物理行:实际看到的代码行数. 逻辑行:在意义上的函数(即解释器执行的行数) 如果一个物理行中包含了多个逻辑行,则每个逻辑行之间需要用分号 ...
- 为什么覆写equals必须要覆写hashCode?
============================================= 原文链接: 为什么覆写equals必须要覆写hashCode? 转载请注明出处! ============= ...
- conda创建py27虚拟环境安装theano(anaconda3)
现在python3已经成为主流的python环境,大部分的package都兼容python3,仍然有一小部分,或者说是某一领域的package需要使用python2.本人现在主要在利用python做机 ...