Hibernate 一级缓存测试分析

Hibernate的一级缓存就是指Session缓存,此Session非http的session会话技术,可以理解为JDBC的Connection,连接会话,Session缓存就是一块内存空间,用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先使用对象的OID(Object ID)在Hibernate 的一级缓存空间进行查找,如果通过OID匹配到了对象,就直接从一级缓存中取出使用,如果没有找到匹配该OID值的对象,这才会进行查询数据库。当从数据库中查询数据的时候,该数据就会被放入到Session缓存中,目的就是为了减少数据库的访问次数,从而提高性能。

Hibernate缓存特点

  • 当应用程序调用Session接口的 save(), update(), saveOrUpdate() 时候,如果缓存中没 有相应的对象,Hb就会自动的把查询信息加入到缓存。
  • 当应用程序调用Session接口的 load(), get(), list() 等查询方法的时候,会进行判断缓存中是否有数据,同摘要。
  • 当应用程序调用Session接口的 close() Session缓存会被清空

接下来进行测试一级缓存

首先测试一级缓存是否存在?对user表的主键为“1”的分别进行两次查询:

    public void demo1 (){
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction(); User user1 = session.get(User.class, "1");
System.out.println(user1);
System.out.println("-------------");
User user2 = session.get(User.class, "1");
System.out.println(user2);
System.out.println(user1 == user2); transaction.commit();
session.close();
}

运行结果:

我们发现第一次执行Session的get()方法的时候,由于一级缓存中没有数据,所以会向数据库发送一条sql语句进行查询,第二次调用get()的时候,则不会发送sql语句,而是从一级缓存中取的,所以user和user2的内存地址相等

一级缓存的快照区


Hibernate向一级缓存放入数据的时候,同时复制一份放到Hibernate快照中,当使用commot()提交事务的时候,同时会清理Session的一级缓存,这是会用OID判断一级缓存中的对象和快照中的对象是否一致,如果一致则执行 update 语句,将缓存中的内容同步到数据库,并且更新快照,这也就实现了不使用 update 语句就可以自动更新数据库,Hibernate快照的作用也就是为了保持缓存中的数据和数据库中的数据的一致性。

快照区代码测试

我们在get的时候设置断点,看到右侧变量 session->persitenceContext->entitlxxx->head,也就是缓存中是为空的



现在继续执行



我们发现在缓存区域已经有了数据了,同时Hibernate 也会在快照区域创建数据,在 Hibernate3 里面它使用的是Map进行存储的,map的key作为一级缓存去,value作为一级快照区,当进行查询的时候,会同时给缓存和快照去放入相同的数据,当orm对象属性发生变化的时候,会首先改变缓存区的值,当进行事务提交的时候,会比较缓存和快照的内容,如果一致则不操作,不一致则更新数据库。

继续执行:



commin()的时候,自动进行更新,clear().evict()的时候会清除缓存(删除表中数据的时候也会)

    public void demo1 (){
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction(); User user1 = session.get(User.class, "1");
System.out.println(user1);
System.out.println("-------------");
session.clear();
User user2 = session.get(User.class, "1");
System.out.println(user2);
System.out.println(user1 == user2); transaction.commit();
session.close();
}

输入如下:

Hibernate:
select
user0_.uid as uid1_1_0_,
user0_.name as name2_1_0_,
user0_.username as username3_1_0_,
user0_.password as password4_1_0_,
user0_.email as email5_1_0_,
user0_.telephone as telephon6_1_0_,
user0_.sex as sex7_1_0_
from
user user0_
where
user0_.uid=?
User{uid=1, username=baiChaoHua, password=null, name=null, email=null, telephone=null, birthady=null, sex=null, state=0, code=null}
-------------
Hibernate:
select
user0_.uid as uid1_1_0_,
user0_.name as name2_1_0_,
user0_.username as username3_1_0_,
user0_.password as password4_1_0_,
user0_.email as email5_1_0_,
user0_.telephone as telephon6_1_0_,
user0_.sex as sex7_1_0_
from
user user0_
where
user0_.uid=?
User{uid=1, username=baiChaoHua, password=null, name=null, email=null, telephone=null, birthady=null, sex=null, state=0, code=null}
false

可以看出执行执行了两次sql,user对象的内存地址也就自然不一样

一级缓存常用的API:

  • clear():清空一级缓存。
  • evict():清空一级缓存中指定的某个对象。
  • refresh():重新查询数据库,用数据库中的信息来更新一级缓存与快照区。

未完待续...

Hibernate一级缓存测试分析的更多相关文章

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

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

  2. hibernate一级缓存

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

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

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

  4. Hibernate一级缓存(补)

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

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

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

  6. Hibernate一级缓存和三种状态

    Hibernate一级缓存又称session缓存,生命周期很短,跟session生命周期相同. 三种状态:1.transient(瞬时态):刚new出来的对象,既不在数据库中,也不在session管理 ...

  7. hibernate一级缓存的源码初窥

    hibernate的一级缓存的存在使得hibernate可以在操作实体化对象的时候减少对于数据库的访问.hibernate的一级缓存实际上就是指的session缓存,它的生命周期和session相同. ...

  8. Hibernate 一级缓存的陷阱

    最近公司的应用经常报OOM,一开始我以为是公司业务数据太多,导致内存不够,所以只是简单的把容器的内存加大.撑了几天后这个错仍然被报出来.后来我仔 细分析过项目代码后,没有发现有任何引起内存泄漏的地方. ...

  9. Hibernate <一级缓存>

    Hibernate缓存分为三级: 一级缓存:基于事务级别(内存)的缓存,也可以成为session级别缓存 二级缓存:依赖于第三方,当请求一个对象时,先在缓存里面查找,如果没有就执行查询语句 查询缓存: ...

随机推荐

  1. 14-n皇后

    /*题目内容: 国际象棋中的皇后可以沿着水平线,垂直线,或者斜线前进,吃掉遇到的所有棋子,如果棋盘上有八个皇后,则这八个皇后如何相安无事的放置在棋盘上,1970年与1971年, E.W.Dijkstr ...

  2. 【转】从源码浅析MVC的MvcRouteHandler、MvcHandler和MvcHttpHandler

    原文:http://www.cnblogs.com/jeffwongishandsome/archive/2012/01/08/2316521.html 熟悉WebForm开发的朋友一定都知道,Pag ...

  3. js深拷贝、浅拷贝

    浅拷贝: 只针对当前对象的属性进行拷贝,若当前对象的属性是引用类型时,这个不考虑,不进行拷贝.若属性是引用类型,拷贝后引用的是地址,如果进行更改,会影响拷贝的原对象属性. 深拷贝:针对当前对象的数据的 ...

  4. vue2.0 tab切换几种方式

    第一种 比较灵活简单的方式(切换改变部分的内容在组件中比较方便操作) <template> <div id="app"> <ul> <li ...

  5. python 调试方法

    一.使用pdb http://blog.csdn.net/wyb_009/article/details/8896744 二.使用gdb 需首先配置gdb pythin支持,步骤如下: 1.修改Pyt ...

  6. ffmpeg 入门教程

    1.在terminal,安装ffmpeg开源库 #brew install ffmpeg 2.新建一个目录first_ffmpeg,并在first_ffmpeg目录下新建ffmpeg目录 3.拷贝/u ...

  7. Monte carlo

    转载 http://blog.sciencenet.cn/blog-324394-292355.html 蒙特卡罗(Monte Carlo)方法,也称为计算机随机模拟方法,是一种基于"随机数 ...

  8. 2018.06.30 BZOJ4443: [Scoi2015]小凸玩矩阵(二分加二分图匹配)

    4443: [Scoi2015]小凸玩矩阵 Time Limit: 10 Sec Memory Limit: 128 MB Description 小凸和小方是好朋友,小方给小凸一个N*M(N< ...

  9. 2018.09.01 hdu4405 Aeroplane chess (期望dp)

    传送门 期望dp简单题啊. 不过感觉题意不太对. 手过了一遍样例发现如果有捷径必须走. 这样的话就简单了啊. 设f[i]" role="presentation" sty ...

  10. Java的进阶之道

    Java的进阶之道 一.温馨提示 尽量用google查找技术资料.(条件允许的话) 有问题在stackoverflow找找,大部分都已经有人回答. 多看官方的技术文档. ibm developerwo ...