Hibernate一级缓存和三种状态
Hibernate一级缓存又称session缓存,生命周期很短,跟session生命周期相同。
三种状态:1.transient(瞬时态):刚new出来的对象,既不在数据库中,也不在session管理内.
2.persistent(持久化状态):在session缓存中,在数据库中可能有记录(注意)。如果一个对象时瞬时态,调用save会变成持久态,但是如果不提交事务的话,数据库是 不会有这条记录的。
3.detached(离线状态):即对象存在于数据库中,但没有被session所管理。
三种状态可以相互转换:
1.瞬时对象(通过new关键字获取):
瞬时---持久:save或者saveOrUpdate
瞬时---脱管:setId()
2.持久化对象(通过get/load或Query查询获取):
持久---瞬时态:delete(),删除持久化对象,不建议再次使用到同一个对象。
持久---离线态:evict()删除session缓存中某个对象,close()清楚session缓存,clear()清除session缓存中所有对象。
3.脱管对象(无法直接获得):
脱管---瞬时:setId(null),删除对象OID
脱管---持久:save或saveOrUpdate或lock
如果对象已经是持久化状态,那么不管对对象做过多次修改,或者操作多次save()或update()方法,都不会发送sql语句。只有在事务提交时,当且仅当当前对象(快照区的对象)与session缓存中的对象不一致时,才会发送update语句。
对于瞬时态对象,调用save方法变为持久化状态,发送insert语句。
对于离线状态,调用update方法变为持久化状态,发送select语句。
一级缓存:
又称session缓存,同session生命周期一样,都很短,属于事务隔离级别。
Hibernate缓存是通过集合实现的,Hibernate封装了map和list集合。Hibernate向一级缓存中存放数据时,同时会保存一份快照数据。当执行flush()时,会比较一级缓存与快照中
的数据,如果不一致,会执行更新。
用处:当要查询的对象在session缓存中已经存在时,将不会再向数据库发送sql语句,而是直接从session缓存中获取对象。
session.get()、session.load()支持一级缓存,createQuery()不支持一级缓存。即即使是两次相同的查询,获得list也是相同的,也会向数据库发起两次查询,iterate支持一级缓存。
get():
session=HibernateUtil.getSession();
Transaction tr=session.beginTransaction();
User user=session.get(User.class,1);
User user1=session.get(User.class,1);
tr.commit();
session.close();
控制台输出:
  
总结:说明get是支持一级缓存的。使用get查询出的对象会放到一级缓存中,下次使用get查询对象时,如果对象已经存在一级缓存中,就直接从缓存中取对象,而不用再从
数据库查对象。
操作:
1.flush():
清出缓存,一个是手动调用flush(),还有就是调用commit()时也会清出缓存;将缓存清出后,就会向数据库发送sql语句。将缓存同步到数据库。首先会将缓存中的数据与快照数据进行比较,如果不一致,才会发出update语句。
session=HibernateUtil.getSession();
Transaction tr=session.beginTransaction();
//此时会产生快照
User user=session.get(User.class,1);
//改变的是快照区的对象
user.setName("XXX");
//手动flush,因为快照区的对象与缓存中的对象有区别,此时会向数据库发送sql语句,但是数据库中的数据并没有发生改变,只有提交事务时,数据库中的数据才会改变。
session.flush();
tr.commit();
session.close();
2.refresh():
将数据库的数据同步到缓存中,这个过程一定会产生更新语句,同步一级缓存和快照。
session=HibernateUtil.getSession();
Transaction tr=session.beginTransaction();
User user=session.get(User.class,1);
user.setName("XXX");
//数据库中的数据同步到一级缓存和快照,向数据库发送一次查询语句
session.refresh(user);
System.out.println(user);
//因为调用了refresh使数据库与一级缓存的对象同步,所以不会向数据库发送update语句。
tr.commit();
session.close();
3.clear():
清空所有对象的一级缓存,对对象的所有操作全部失效,恢复到原来快照的数据
session=HibernateUtil.getSession();
Transaction tr=session.beginTransaction();
User user=session.get(User.class,1);
user.setName("XXX");
//调用clear清空了session缓存所有数据,数据库不会发生任何变化
session.clear();
tr.commit();
session.close();
4.evict():
对指定的对象清除一级缓存
session=HibernateUtil.getSession();
Transaction tr=session.beginTransaction();
User user1=session.get(User.class,1);
User user2=session.get(User.class,2);
//清除一级缓存中的user1的所有修改操作
session.evict(user1);
//调用get获取id为1的user时还会向数据库发送sql语句
User user11=session.get(User.class,1);
User user22=session.get(User.class,2);
tr.commit();
session.close();

总结:因为对user1调用了evict()方法,user1在一级缓存中被清除,所以再次get()id为1的对象时,在缓存中没有该对象,会向数据库再次发送sql语句。
Hibernate一级缓存和三种状态的更多相关文章
- hibernate - 一级缓存和三种状态解析
		
转载自:http://www.cnblogs.com/whgk/p/6103038.html 一.一级缓存和快照 什么是一级缓存呢? 很简单,每次hibernate跟数据库打交道时,都是通过sessi ...
 - hibernate(二)一级缓存和三种状态解析
		
序言 前一篇文章知道了什么是hibernate,并且创建了第一个hibernate工程,今天就来先谈谈hibernate的一级缓存和它的三种状态,先要对着两个有一个深刻的了解,才能对后面我要讲解的一对 ...
 - Hibernate学习(二)———— 一级缓存和三种状态解析
		
一.一级缓存和快照 什么是一级缓存呢? 很简单,每次hibernate跟数据库打交道时,都是通过session来对要操作的对象取得关联,然后在进行操作,那么具体的过程是什么样的呢? 1.首先sessi ...
 - 一级缓存、二级缓存、延迟加载、hibernate session 域  pojo三种状态
		
1.一级缓存(session缓存 ).二级缓存 意义:提高hibernate查询效率. 缺点:可能会因并发,产生数据不一致. 本质:基于session 的缓存,利用hiber ...
 - Hibernate持久化对象的三种状态深入理解
		
关于OID hibernate缓存是一个map,他会根据OID作为缓存对象的key,我们的映射文件中<id>标签指定的属性值会作为OID 持久化对象的三种状态 为了方便理解,Hiberna ...
 - 【SSH系列】-- Hibernate持久化对象的三种状态
		
在上一篇博文中,小编主要简单的介绍了[SSH系列]--hibernate基本原理&&入门demo,今天小编来继续介绍hibernate的相关知识, 大家知道,Java对象的生命周期,是 ...
 - Hibernate之对象的三种状态
		
Hibernate之Java对象的三种状态 一.简述 本博文大部分的思想和内容引子CSND上名为 FG2006 这位大神的文章,连接地址为:http://blog.csdn.net/fg2006/ar ...
 - hibernate一级缓存及对象的状态
		
hibernate中实体类对象的状态 在hibernate中实体类对象有三种状态 (1)瞬时态(临时态) 瞬时态:即我们自己创建一个对象,还没有保存到数据库就叫临时态,其实也可以说是对像没有id值,跟 ...
 - Hibernate中对象的三种状态及相互转化
		
1. 瞬时状态 (Transient) 当我们通过Java的new关键字来生成一个实体对象时,这时这个实体对象就处于自由状态,如下: Customer customer=new Customer(“ ...
 
随机推荐
- javascript获取元素样式值
			
使用css控制页面有4种方式,分别为行内样式(内联样式).内嵌式.链接式.导入式. 行内样式(内联样式)即写在html标签中的style属性中,如<div style="width:1 ...
 - Python-并发编程(协程)
			
今天说说协程 一.引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两 ...
 - Activiti学习之HelloWorld程序
			
流程图 部署流程定义 /** * 部署流程定义 */ @Test public void deploymentProcessDefinition() { ProcessEngine processEn ...
 - MySQL数据库(4)----生成统计信息
			
MySQL最有用的一项功能就是,能够对大量原始数据进行归纳统计. 1.在一组值里把各个唯一的值找出来,这是一项典型的统计工作,可以使用DISTINCT 关键字清楚查询结果里重复出现的行.例如,下面的查 ...
 - 佣金百万so easy!阿里云推广联盟喊你来赚钱
			
淘客速来,佣金百万so easy!阿里云推广联盟喊你来赚钱 阿里云CPS推广阶梯返佣活动火热升级! 坐享15%佣金!一笔成交即有奖励!最高奖励2000元! 超高客单价.高转化率.高佣金! 招募淘客推广 ...
 - javascript  匿名函数及闭包----转载
			
网上很多解释,我无法理解,我想知道原理...这篇文章应该可以透彻一点Query片段:view plaincopy to clipboardprint? (function(){ //这里忽略 ...
 - 如何在 Maven 工程中引入其他jar包 并生效?(以 Netty 为例)
			
1.到 Maven 官网 查找 相关 框架 https://mvnrepository.com/artifact/io.netty/netty-all/4.1.32.Final 2.把相关 Xml体 ...
 - Oracle案例04——TNS-12547: TNS:lost contact
			
Oracle数据库服务器DG从库重启后,无法完成数据同步,具体报错信息如下: 一.报错信息 alter log报错 ****************************************** ...
 - 安装python  File "/usr/bin/pip", line 11, in <module>     sys.exit(main())   File "/usr/lib/python3.4/site-packages/pip/__init__.py", line 215, in main     locale.setlocale(locale.LC_ALL, '')   File "/u
			
$ uname -a Linux debian 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1+deb8u6 (2015-11-09) x86_64 GNU ...
 - BUG Review:关于getting 'android:xxx' attribute: attribute is not a string value的问题及解决方法
			
我们在使用Android Studio开发完应用程序后,都要将打好的apk安装包上传到各大应用市场,但是有时候上传时应用市场会出现提交的安装包不能通过应用市场的aapt解析而被打回的情况. 他们使用a ...