hibernate一级缓存的源码初窥
hibernate的一级缓存的存在使得hibernate可以在操作实体化对象的时候减少对于数据库的访问.hibernate的一级缓存实际上就是指的session缓存,它的生命周期和session相同.hibernate通过Map来实现一级缓存,Map里存储了持久化类的更新后的状态以及持久化类的副本(又称为快照).
hibernate的session对象于一级缓存相关的结构图如下图所示:

下面通过在eclipse环境下debug,来观察一级缓存在session进行刷新的时候,所涉及到的数据结构和操作.
准备工作:
在数据库中有一个category的表,它有两个字段,cid和cname,其中cid是auto_increment(自动增长)的.在domain包下面建立一个Category的实体类,它的属性名和字段完全保持一致.
编写以下的代码,在session.flush这一行处打一个断点,debug运行,进入该行
@Test
public void testContent() {
Session session=HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
Category category3=session.get(Category.class,2);
category3.setCname("我很爱吃");
session.flush();
transaction.commit();
}
在断点处进入,并且向下运行,会跳入AbstractFlushingEventListener的flushEntities方法.从这个方法的描述如下:
1.detect any dirty entities
2. schedule any entity updates
3.search out any reachable collections
可以看出来,这个方法就是发现脏数据并且为更新操作做准备.这个方法有如下代码:
final Map.Entry<Object,EntityEntry>[] entityEntries = persistenceContext.reentrantSafeEntityEntries();
将鼠标移动到entityEntries这个对象上,可以发现,它是一个键为实体类对象,值为EntityEntry的一个Map的entry对象,相关解释如下图:
方法继续进行,将会把Entry对象的键和值交给一个onFlushEntity的方法,这个方法将会判断有没有脏数据,并且最终判断需不需要向数据库中发送SQL语句.进入这个方法.可以看出这个方法获取到了实体类.原来Entry对象的键和EntityEntry这个对象(原来Entry对象的值.里面包含快照).随后调用EntityEntry对象的requiresDirtyCheck方法,判断是否需要进行脏检查.
判断结果将会赋值给一个叫做mightBeDirty的boolean类型的变量.然后根据此变量判断是否需要向数据库发出sql语句.
这就是在一级缓存中的实体类对象发生更新后,hibernate进行脏检查和内存中的快照(实际上,就是loadState数组.它的长度取决于具有业务含义的字段的个数)进行比对,并且发出sql语句的大致过程.由于水平的原因,只能分析源代码到这里,感觉hibernate的源代码还是相当复杂的,在以后的学习中也要多多看看源代码,观看大神的代码规范和理解它们的思路,对于自己进行编码一定会有很大的帮助!
hibernate一级缓存的源码初窥的更多相关文章
- Hadoop学习笔记(9) ——源码初窥
Hadoop学习笔记(9) ——源码初窥 之前我们把Hadoop算是入了门,下载的源码,写了HelloWorld,简要分析了其编程要点,然后也编了个较复杂的示例.接下来其实就有两条路可走了,一条是继续 ...
- Hibernate一级缓存(补)
------------------siwuxie095 什么是缓存 缓存是介于应用程序和永久性数据存储源(如:硬盘上的 ...
- hibernate一级缓存
理解 Hibernate 一级缓存 Hibernate 一级缓存默认是打开,不需要任何的配置.实际上,你无法强制禁止它的使用. 如果你理解了一级缓存实际上和会话是关联的,就很容易理解一级缓存.总所周知 ...
- Hibernate一级缓存(基于查询分析)
首先我们应该弄清什么是hibernate缓存:hibernate缓存是指为了降低应用程序对物理数据源的访问频次,从而提高应用程序的运行性能的一种策略.我们要将这个跟计算机内存或者cpu的缓存区分开. ...
- Java禁止浏览器有缓存的源码
Java禁止浏览器有缓存的源码 import java.io.IOException; import javax.servlet.Filter; import javax.servlet.Filter ...
- hibernate一级缓存及对象的状态
hibernate中实体类对象的状态 在hibernate中实体类对象有三种状态 (1)瞬时态(临时态) 瞬时态:即我们自己创建一个对象,还没有保存到数据库就叫临时态,其实也可以说是对像没有id值,跟 ...
- wifidog 源码初分析(4)-转
在上一篇<wifidog 源码处分析(3)>的流程结束后,接入设备的浏览器重定向至 路由器 上 wifidog 的 http 服务(端口 2060) /wifidog/auth 上(且携带 ...
- Hibernate一级缓存测试分析
Hibernate 一级缓存测试分析 Hibernate的一级缓存就是指Session缓存,此Session非http的session会话技术,可以理解为JDBC的Connection,连接会话,Se ...
- 转载 hibernate一级缓存和二级缓存的区别
文章来源:http://blog.csdn.net/defonds/article/details/2308972 hibernate一级缓存和二级缓存的区别 缓存是介于应用程序和物理数据源之 ...
随机推荐
- JS调用OC方法并传值,OC调用JS方法并传值////////////////////////zz
iOS开发-基于原生JS与OC方法互相调用并传值(附HTML代码) 最近项目里面有有个商品活动界面,要与web端传值,将用户在网页点击的商品id 传给客户端,也就是js交互,其实再说明白一点 ...
- bzoj3884 上帝与集合的正确用法
a^b mod P=a^(b mod phi(p)) mod p,利用欧拉公式递归做下去. 代码 #pragma comment(linker,"/STACK:1024000000,1024 ...
- Java以基础类库
Java以基础类库JFC(Java Foundation Class)的形式为程序员提供编程接口API,类库中的类按照用途归属于不同的包中. (一)java.lang包 Java最常用的包都属于该包, ...
- react.js语法为了更好的兼容可以选以下这种方法配置即可
首先下一个sublime text3 的编辑器: 支持大家使用正版,不过我是为了方便才所以这版本而已... 地址: http://sublimetext.iaixue.com/forum.php?mo ...
- html5,单击文字自动获得焦点
<p><label for=""></label>这样单击后自动获得焦点</p>
- Arduino蓝牙模块实现通信
蓝牙参数特点 1.蓝牙核心模块使用HC-06从模块,引出接口包括VCC,GND,TXD,RXD,预留LED状态输出脚,单片机可通过该脚状态判断蓝牙是否已经连接 2.led指示蓝牙连接状态,闪烁表示没有 ...
- EditPlus 3.6 中文版已经发布(2013年12月17日)
新版的EditPlus 3.6修复了多项问题,并新增了函数列表面板.按F2.Ctrl+F2等快捷键可弹出输入提示窗格. 我已同步汉化最新版,请点击右上角的连接下载.
- Something about Linux
Linux-一切皆文件 VMnet1 Host-Only网络下的虚拟交换机 VMnet8 虚拟NAT网络下的虚拟交换机 桥接模式 虚拟出同一网段下都能访问的服务器 ---------- ...
- ios webView 放大网页解决/input 获得焦点focus 网页放大 解决
新手遇到的问题: 终于找到原因,各种HTML viewport 都试过 setScalePageToFit 也试过,webViewDidFinishLoad加JS代码,动态算webView.scrol ...
- YbSoftwareFactory 代码生成插件【二十四】:MVC中实现动态自定义路由
上一篇介绍了 公文流转系统 的实现,本篇介绍下MVC下动态自定义路由的实现. 在典型的CMS系统中,通常需要为某个栏目指定个友链地址,通过指定友链地址,该栏目的地址更人性化.方便记忆,也有利用于搜索引 ...