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一级缓存和二级缓存的区别 缓存是介于应用程序和物理数据源之 ...
随机推荐
- 常用的Linux命令
1.如何创建一个目录?mkdir DirectoryName 2.如何进入服务器根目录?ls / 3.如何查看日历?cal 4.如何修改密码?passwd 5.如何查看当前用户信息?whoami 6. ...
- 00Linux学习及角色定义
一.嵌入式Linux学习顺序 二.Linux架构 三.Linux工程师角色划分 四. 嵌入式应用工程师工作内容与所需知识点 从图 1可以知道, 嵌入式应用工程师主要从事与产品相关的嵌入式 Linux ...
- Python函数信息
Python函数func的信息可以通过func.func_*和func.func_code来获取 一.先看看它们的应用吧: 1.获取原函数名称: 1 >>> def yes():pa ...
- iOS 图片的按照比例拉伸
// 这是一个UIImage 的分类 ( UIImage+Extension.h ) UIImage+Extension.h #import <UIKit/UIKit.h> @int ...
- Linux的fasync驱动异步通知详解【转】
本文转载自:http://blog.csdn.net/coding__madman/article/details/51851338 版权声明:本文为博主原创文章,未经博主允许不得转载. 工作项目用有 ...
- MySQL乱码问题
JSP的request 默认为ISO8859_1,所以在处理中文的时候, 要显示中文的话,必须转成GBK的,如下 String str=new String(request.getParamete ...
- 让C#轻松实现读写锁分离
ReaderWriterLockSlim 类 表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问. 使用 ReaderWriterLockSlim 来保护由多个线程读取但每次只采用一 ...
- SVN批处理
前言 我们在项目开发中,使用的版本管理工具有svn git等.这里介绍一下用 bat命令操作svn .这样会给我们带来很大的方便. bat命令 Python等大家一定要掌握哈,会给你带来很多的方便.其 ...
- 利用JavaScript来实现省份—市县的二级联动
所谓省-市二级联动是指当选择省份下拉选择框时,市县的下拉框会根据选择的省市而有相应的市县加载出来,如下图所示选择"上海市",城市的下拉选择框只会出现上海的市县: 这种二级联动非常常 ...
- PowerShell脚本自动设置安卓手机wifi代理
在实际测试工作中,经常要将安卓手机通过wifi代理的形式连接到本机的fiddler或charles服务器代理进行抓包测试.最近一直在想,有没有什么方法可以自动设置安卓手机的wifi代理,曾经想通过修改 ...