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运行,进入该行
@Testpublic 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的源代码还是相当复杂的,在以后的学习中也要多多看看源代码,观看大神的代码规范和理解它们的思路,对于自己进行编码一定会有很大的帮助!
转载于:https://www.cnblogs.com/hlhdidi/p/6139020.html
hibernate一级缓存的源码初窥相关推荐
- Spring AOP 源码初窥(二) 从注解开始
版本 spring 5.0.8.BUILD-SNAPSHOT aspectjweaver 1.8.13 从注解开始 由于在本人实际应用中使用的是注解配置AOP,也更倾向于了解Spring AOP的整个 ...
- Hibernate一级缓存
2019独角兽企业重金招聘Python工程师标准>>> import java.io.Serializable; import org.hibernate.Session; impo ...
- Mybatis 缓存系统源码解析
Mybatis 缓存系统源码解析 转载于:https://juejin.im/post/5bfa50905188251d0920006c
- hibernate一级缓存_Hibernate缓存–一级缓存
hibernate一级缓存 Welcome to Hibernate Caching – First Level Cache Example Tutorial. Recently we looked ...
- wifidog 源码初分析
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://quietmadman.blog.51cto.com/3269500/138629 ...
- Python concurrent.future 使用教程及源码初剖
前言 原文发在这里的 Python concurrent.future 使用教程及源码初剖 垃圾话 很久没写博客了,想了想不能再划水,于是给自己定了一个目标,写点 concurrent.future ...
- 从 Preact 源码一窥 React 原理(二):Diff 算法
从 Preact 源码一窥 React 原理(二):Diff 算法 前言 Diff 算法 渲染 diffChildren 函数 diff 函数 diffElementNodes 函数 diffProp ...
- 从 Preact 源码一窥 React 原理(一):JSX 渲染
从 Preact 源码一窥 React 原理(一):JSX 渲染 前言 JSX 渲染 VNode createElement 函数 coerceToVNode 函数 总结 参考资料 系列文章: 从 P ...
- Hibernate 一级缓存,二级缓存,查询缓存
概念: 1.什么是缓存呢? 缓存:是计算机领域的概念,它介于应用程序和永久性数据存储源之间. 缓存:一般人的理解是在内存中的一块空间,可以将二级缓存配置到硬盘.用白话来说,就是一个存储数据的容器.我们 ...
- 【Mybatis】一二级缓存的源码研究
Mybatis的一级缓存 Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言.所以在参数和SQL完全一样的情况下,我们使用同一 ...
最新文章
- R语言使用GGally包的ggparcoord函数可视化多变量的平行坐标轴图(parallel coordinates plot)、当排序点图的数据对象变多的可视化效果变差的时候
- C/C++左值性精髓(二)哪些表达式是左值,哪些是右值?----右值表达式
- Nginx-从零开始使用nginx实现反向代理及负载均衡
- 一个java文件中多个类
- sqoop2 java api实现_Sqoop2 Java客户端API指南
- 程序员的搞笑日常:写给1024的程序员们,现在的你们还在加班吗?
- 编译源码时出现 Checking API: checkapi-last (unknown): error 17解决方法
- Win8.1/Win10在某些程序输入中文变成问号的解决方法
- Javascript算法系列之快速排序(Quicksort)
- 【转】我是你的过客,你却是我的定格......
- 水星无线路由启动dhcp服务器,水星无线路由器桥接设置桥接(图文详解) | 192.168.1.1登陆页面...
- 【读书摘抄】人类简史
- 5类网线,超5类网线,6类网线,超6类网线的区别
- wps怎么减少行间距,WPS的word怎么不能缩小行间距
- cocos creator如何实现微信好友自定义转发分享功能
- CENTOS5.5下使用Roundcube搭建 Webmail
- Microsoft IIS波浪号目录枚举/IIS短文件名枚举漏洞
- HashMap中put方法(白话加源码分析)
- android 双屏壁纸,高清全面屏双屏壁纸
- 【产业互联网】产业互联网的未来大发展
热门文章
- 陶哲轩实分析 习题 12.5.4,12.5.5
- [原]浅谈几种服务器端模型——多进程并发式
- Net设计模式实例之桥接模式( Bridge Pattern)(4)
- spark Transformations算子
- springboot2的redis缓存管理器cacheManager配置,使存入json格式数据
- 父级div没高度不能自适应高度的原因——子级使用css float浮动
- 没有Path的Binding
- (翻译)《介绍 GENEVA Beta 1 白皮书》(3)
- intellij idea参数提示param hints
- 3-13 图片几何变换小结