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一级缓存和二级缓存的区别 缓存是介于应用程序和物理数据源之 ...
随机推荐
- jQuery.serialize() 函数详解////////////z
serialize()函数用于序列化一组表单元素,将表单内容编码为用于提交的字符串. serialize()函数常用于将表单内容序列化,以便用于AJAX提交. 该函数主要根据用于提交的有效表单控件的n ...
- HTML5--拖动01
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- Java程序员学习之路
1. Java语言基础 谈到Java语 言基础学习的书籍,大家肯定会推荐Bruce Eckel的<Thinking in Java>.它是一本写的相当深刻的技术书籍,Java语言基础部分基 ...
- AS配置IDE
字体调整 settings->editor->colors&fonts->font,必须save as一个名称,个人选择Courier New字体,大小为14: 快捷键设置 ...
- iOS 图片的按照比例拉伸
// 这是一个UIImage 的分类 ( UIImage+Extension.h ) UIImage+Extension.h #import <UIKit/UIKit.h> @int ...
- C#的HTTP协议中POST与GET的区别
引言 HTTP协议我想任何IT人士都耳熟能详了,大家都能说出个所以然来.但是如果我问你HTTP协议的请求方法有哪些?POST与GET的差异?GET或POST传送数据量的大小有限制吗?HTTP响应的状态 ...
- iOS多线程同步锁
在iOS中有几种方法来解决多线程访问同一个内存地址的互斥同步问题: 方法一,@synchronized(id anObject),(最简单的方法)会自动对参数对象加锁,保证临界区内的代码线程安全 @s ...
- 可用的rtmp互联网地址
rtmp://live.hkstv.hk.lxdns.com/live/hks 测试可用. vlc使用ffmpeg取rtmp网络流. 代码文件路径: vlc-2.2.1\modules\access\ ...
- MySQL获取汉字的首字母
)) ) CHARSET utf8 BEGIN ); )),,), 0xB0A1,0xB0C5,0xB2C1,0xB4EE,0xB6EA,0xB7A2,0xB8C1,0xB9FE,0xBBF7, 0x ...
- androi 多线程
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q ...