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一级缓存的源码初窥的更多相关文章

  1. Hadoop学习笔记(9) ——源码初窥

    Hadoop学习笔记(9) ——源码初窥 之前我们把Hadoop算是入了门,下载的源码,写了HelloWorld,简要分析了其编程要点,然后也编了个较复杂的示例.接下来其实就有两条路可走了,一条是继续 ...

  2. Hibernate一级缓存(补)

    ------------------siwuxie095                                 什么是缓存         缓存是介于应用程序和永久性数据存储源(如:硬盘上的 ...

  3. hibernate一级缓存

    理解 Hibernate 一级缓存 Hibernate 一级缓存默认是打开,不需要任何的配置.实际上,你无法强制禁止它的使用. 如果你理解了一级缓存实际上和会话是关联的,就很容易理解一级缓存.总所周知 ...

  4. Hibernate一级缓存(基于查询分析)

    首先我们应该弄清什么是hibernate缓存:hibernate缓存是指为了降低应用程序对物理数据源的访问频次,从而提高应用程序的运行性能的一种策略.我们要将这个跟计算机内存或者cpu的缓存区分开. ...

  5. Java禁止浏览器有缓存的源码

    Java禁止浏览器有缓存的源码 import java.io.IOException; import javax.servlet.Filter; import javax.servlet.Filter ...

  6. hibernate一级缓存及对象的状态

    hibernate中实体类对象的状态 在hibernate中实体类对象有三种状态 (1)瞬时态(临时态) 瞬时态:即我们自己创建一个对象,还没有保存到数据库就叫临时态,其实也可以说是对像没有id值,跟 ...

  7. wifidog 源码初分析(4)-转

    在上一篇<wifidog 源码处分析(3)>的流程结束后,接入设备的浏览器重定向至 路由器 上 wifidog 的 http 服务(端口 2060) /wifidog/auth 上(且携带 ...

  8. Hibernate一级缓存测试分析

    Hibernate 一级缓存测试分析 Hibernate的一级缓存就是指Session缓存,此Session非http的session会话技术,可以理解为JDBC的Connection,连接会话,Se ...

  9. 转载 hibernate一级缓存和二级缓存的区别

    文章来源:http://blog.csdn.net/defonds/article/details/2308972     hibernate一级缓存和二级缓存的区别 缓存是介于应用程序和物理数据源之 ...

随机推荐

  1. jQuery.serialize() 函数详解////////////z

    serialize()函数用于序列化一组表单元素,将表单内容编码为用于提交的字符串. serialize()函数常用于将表单内容序列化,以便用于AJAX提交. 该函数主要根据用于提交的有效表单控件的n ...

  2. HTML5--拖动01

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  3. Java程序员学习之路

    1. Java语言基础 谈到Java语 言基础学习的书籍,大家肯定会推荐Bruce Eckel的<Thinking in Java>.它是一本写的相当深刻的技术书籍,Java语言基础部分基 ...

  4. AS配置IDE

    字体调整 settings->editor->colors&fonts->font,必须save as一个名称,个人选择Courier New字体,大小为14: 快捷键设置 ...

  5. iOS 图片的按照比例拉伸

    // 这是一个UIImage 的分类 (  UIImage+Extension.h   ) UIImage+Extension.h #import <UIKit/UIKit.h> @int ...

  6. C#的HTTP协议中POST与GET的区别

    引言 HTTP协议我想任何IT人士都耳熟能详了,大家都能说出个所以然来.但是如果我问你HTTP协议的请求方法有哪些?POST与GET的差异?GET或POST传送数据量的大小有限制吗?HTTP响应的状态 ...

  7. iOS多线程同步锁

    在iOS中有几种方法来解决多线程访问同一个内存地址的互斥同步问题: 方法一,@synchronized(id anObject),(最简单的方法)会自动对参数对象加锁,保证临界区内的代码线程安全 @s ...

  8. 可用的rtmp互联网地址

    rtmp://live.hkstv.hk.lxdns.com/live/hks 测试可用. vlc使用ffmpeg取rtmp网络流. 代码文件路径: vlc-2.2.1\modules\access\ ...

  9. MySQL获取汉字的首字母

    )) ) CHARSET utf8 BEGIN ); )),,), 0xB0A1,0xB0C5,0xB2C1,0xB4EE,0xB6EA,0xB7A2,0xB8C1,0xB9FE,0xBBF7, 0x ...

  10. androi 多线程

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q ...