深入了解Hibernate的缓存使用
Hibernate缓存
缓存是计算机领域的概念,它介于应用程序和永久性数据存储源(如在硬盘上的文件或者数据库)之间,其作用是降低应用程序
直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的复制,应用程序在运行时直接
读写缓存中的数据,只在某些特定时刻按照缓存中的数据来同步更新数据存储源。
缓存的物理介质通常是内存,而永久性数据存储源的物理介质通常是硬盘或磁盘,应用程序读写内存的速度显然比读写硬盘的速度
快。如果缓存中存放的数据量非常大,也会用硬盘作为缓存的物理介质。
Hibernate缓存一般分为3类:
(1)一级缓存。Session缓存称为一级缓存。由于Session对象的生命周期通常对应一个数据库事务,因此它的缓存是事务范围的缓存。
一级缓存是必需的,Session默认带有,而且不能卸载。在一级缓存中,持久化类的每个实例都具有唯一的OID。
(2)二级缓存。SessionFactory缓存分为内置缓存和外置缓存。内置缓存是Hibernate自带的,不可拆卸,是只读缓存,用来存放映射
元数据和预定义SQL语句。外置缓存是一个可配置的缓存插件,默认SessionFactory不会启用这个缓存插件。外置缓存中的数据是数据库
数据的复制。SessionFactory对象的生命周期和应用程序的整个进程对应。二级缓存是可选的,可以在每个类或每个集合的粒度上配置二
级缓存。
(3)查询缓存。它是Hibernate为查询结果提供的,依赖于二级缓存。
缓存的作用分为3类
(1)事务范围。每个事务都有自己的缓存,缓存内数据不会被多个事务并发访问。例如hibernate的一级缓存,事务是不能跨多个Session的,Session内
数据只能被当前事务访问,因此它属于事务范围的缓存。
(2)进程范围。进程内的所有事物共享缓存,进程结束,缓存结束生命周期,例如hibernate的二级缓存,SessionFactory对象的生命周期对应应用程序的
整个进程,因此它属于进程范围的缓存。
(3)集群范围。缓存被一个或多个机器上的多个进程共享。Hibernate的二级缓存也可以作为集群范围的缓存。
一级缓存:
一级缓存的生命周期和session的生命周期一致,当前session一旦关闭,一级缓存就消失了,因此一级缓存也叫session级的缓存或事务级缓存,一级缓存只存实体对象,它不会缓存一般的对象属性(查询缓存可以),即当获得对象后,就将该对象缓存起来,如果在同一session中再去获取这个对象时,它会先判断在缓存中有没有该对象的id,如果有则直接从缓存中获取此对象,反之才去数据库中取,取的同时再将此对象作为一级缓存处理。
|
|||
|
|||
以下方法支持一级缓存:
* get()
* load()
* iterate(查询实体对象)
其中 Query 和Criteria的list() 只会缓存,但不会使用缓存(除非结合查询缓存)。
二级缓存:
开发中的用途没有面试带来作用大。
二级缓存是进程(N个事务)或集群范围内的缓存,可以被所有的Session共享,在多个事务之间共享
二级缓存是可配置的插件
配置二级缓存的步骤:
*1.引入如下jar包。
ehcache-1.2.3.jar 核心库
backport-util-concurrent.jar
commons-logging.jar
*2.配置Hibernate.cfg.xml开启二级缓存
<property name="hibernate.cache.use_second_level_cache">true</property>
*3.配置二级缓存的供应商
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
*4.指定使用二级缓存的类
方案一:在*.hbm.xml中配置
在<class>元素的子元素下添加chche子节点,但该配置仅会缓存对象的简单属性,若希望缓存集合属性中的元素,必须在set元素中添加<cache>子元素
<class name="Student" table="STUDENT">
<cache usage="read-write"/>
方案二:在大配置文件(hibernate.cfg.xml)中配置
位置有限定
Multiple annotations found at this line:
- The content of element type "session-factory" must match "(property*,mapping*,(class-cache|collection-
cache)*,event*,listener*)".
- Start tag of element <session-factory>
<class-cache usage="read-write" class="cn.happy.entity.Student"/>
<collection-cache usage="read-write" collection=""/>
*5.在src下添加ehcache.xml文件,从etc获取文件即可。
解析 :出现如下错误因为没有添加二级缓存所需jar包
org.hibernate.HibernateException: could not instantiate RegionFactory [org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge]
二级缓存分为:
缓存算法
类级别缓存区
集合级别缓存区
更新时间戳
查询缓存
query 的list()和iterate()区别 (必记)
解析:
1.返回的类型不一样,list返回List,iterate返回Iterator,
2.获取数据的方式不一样,list会直接查数据库,iterate会先到数据库中把id都取出来,然后真正要遍历某个对象的时候先到缓存中找,如果找不到,以id为条件再发一条sql到数据库,这样如果缓存中没有数据,则查询数据库的次数为n+1。
3.iterate会查询2级缓存,list 只会缓存,但不会使用缓存(除非结合查询缓存)。
4.list中返回的List中每个对象都是原本的对象,iterate中返回的对象是代理对象
查询缓存:
1查询是数据库技术中最常用的操作,Hibernate为查询提供了缓存,用来提高查询速度,优化查询性能
相同HQL语句检索结果的缓存!
2查询缓存依赖于二级缓存
查询缓存是针对普通属性结果集的缓存,对实体对象的结果集只缓存id(其id不是对象的真正id,可以看成是HQL或者SQL语句,它与查询的条件相关即where后的条件相关,不同的查询条件,其缓存的id也不一样)。查询缓存的生命周期,当前关联的表发生修改或是查询条件改变时,那么查询缓存生命周期结束,它不受一级缓存和二级缓存生命周期的影响,要想使用查询缓存需要手动配置如下:
* 在hibernate.cfg.xml文件中启用查询缓存,如:
<property name="hibernate.cache.use_query_cache">true</property>
* 在程序中必须手动启用查询缓存,如:
query.setCacheable(true);
其中 Query 和Criteria的list() 就可利用到查询缓存了。
案例:
//查询缓存
@Test
public void queryTest(){ Session session = HibernateUtils.currentSession();
Transaction tx=session.beginTransaction();
List<Dept> list = session.createQuery("from Dept").setCacheable(true).list();
System.out.println(list.get(0).getDeptName()); tx.commit();
HibernateUtils.closeSession();
Session session2 = HibernateUtils.currentSession();
Transaction tx2=session2.beginTransaction();
List<Dept> list2 = session2.createQuery("from Dept").setCacheable(true).list();
System.out.println(list.get(0).getDeptName());
tx2.commit(); }
总结:
不要想当然的以为缓存可以提高性能,仅仅在你能够驾驭它并且条件合适的情况下才是这样的。hibernate的二级缓存限制还是比较多的。在不了解原理的情况下乱用,可能会有1+N的问题。不当的使用还可能导致读出脏数据。 如果受不了hibernate的诸多限制,那么还是自己在应用程序的层面上做缓存吧。
在越高的层面上做缓存,效果就会越好。就好像尽管磁盘有缓存,数据库还是要实现自己的缓存,尽管数据库有缓存,咱们的应用程序还是要做缓存。因为底层的缓存它并不知道高层要用这些数据干什么,只能做的比较通用,而高层可以有针对性的实现缓存,所以在更高的级别上做缓存,效果也要好些吧。
缓存是位于应用程序与物理数据源之间,用于临时存放复制数据的内存区域,目的是为了减少应用程序对物理数据源访问的次数,从而提高应用程序的运行性能.
Hibernate在查询数据时,首先到缓存中去查找,如果找到就直接使用,找不到的时候就会从物理数据源中检索,所以,把频繁使用的数据加载到缓存区后,就可以大大减少应用程序对物理数据源的访问,使得程序的运行性能明显的提升.
深入了解Hibernate的缓存使用的更多相关文章
- hibernate笔记--缓存机制之 二级缓存(sessionFactory)和查询缓存
二级缓存(sessionFactory): Hibernate的二级缓存由SessionFactory对象管理,是应用级别的缓存.它可以缓存整个应用的持久化对象,所以又称为“SessionFactor ...
- Hibernate ——二级缓存
一.Hibernate 二级缓存 1.Hibernate 二级缓存是 SessionFactory 级别的缓存. 2.二级缓存分为两类: (1)Hibernate内置二级缓存 (2)外置缓存,可配置的 ...
- hibernate一级缓存
理解 Hibernate 一级缓存 Hibernate 一级缓存默认是打开,不需要任何的配置.实际上,你无法强制禁止它的使用. 如果你理解了一级缓存实际上和会话是关联的,就很容易理解一级缓存.总所周知 ...
- paip. 提升性能---hibernate的缓存使用 总结
paip. 提升性能---hibernate的缓存使用 总结 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog ...
- 配置Hibernate二级缓存时,不能初始化RegionFactory的解决办法
配置Hibernate 二级缓存时,出现以下bug提示: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder&quo ...
- Hibernate 所有缓存机制详解
hibernate提供的一级缓存 hibernate是一个线程对应一个session,一个线程可以看成一个用户.也就是说session级缓存(一级缓存)只能给一个线程用,别的线程用不了,一级缓存就是和 ...
- [转] 关于hibernate的缓存使用
http://blog.csdn.net/woshichenxu/article/details/586361 1. 关于hibernate缓存的问题: 1.1.1. 基本的缓 ...
- Hibernate的缓存技术详解
转载注明出处:http://www.cnblogs.com/xiaoming0601/p/5882980.html 一.什么是缓存: 并不是指计算机的内存或者CPU的一二级缓存:缓存是指为了降低应用程 ...
- 记录Hibernate的缓存知识
一.Hibernate缓存的作用 Hibernate是一个持久层框架,Hibernate要经常访问物理数据库.为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能,Hibernate的缓 ...
- Spring控制Hibernate的缓存机制ehcache
首先在spring.xml中进入bean <prop key="hibernate.cache.use_second_level_cache">true</pro ...
随机推荐
- webapi 解决ajax跨域请求问题
webapi在配置文件中加入这几句就可以解决ajax(同源策略是JavaScript里面的限制,其他的编程语言,比如在C#,Java或者iOS等其他语言中是可以调用外部的WebService,也就是 ...
- [SDN] What is SDN?
本篇学习笔记写于 Sun Nov 13 15:08:02 2016, 可能有认识不全面的地方. 参考资料为ONF的官方网站中: Software-Defined Networking (SDN) De ...
- 欧姆龙PLC---FINS/TCP
ETN 21 以太网fins/tcp命令 (1)将电脑和PLC设置为同一个网段 例如电脑IP为192.168.18.214,PLC的IP为192.168.18.4(PLC的端口默认为9600) (2) ...
- UITableViewCell的cell重用原理
iOS设备的内存有限,如果用UITableView显示成千上万条数据, 就需要成千上万个UITableViewCell对象的话, 那将会耗尽iOS设备的内存.要解决该问题,需要重用UITableVie ...
- FireFox中iframe的返回上页问题
-----已测试,可以使用----- 原文地址链接:http://fansofjava.iteye.com/blog/1019852 在写静态页面过程中遇到了FF的history.back()和his ...
- 学的一点点ps
从C语言的代码中解脱开始学ps,看到色彩鲜明的东西,心里只有那么爽.哈哈.只学习3天,虽然只是一些皮毛,可还是学到了一些以前不知道的东西.让我对ps多了很多兴趣,决定以后要自学更多的ps技能.要给图片 ...
- XMLHttpRequest upload属性
一.新版本的XMLHttpRequest对象,传送数据的时候,有一个progress事件,用来返回进度信息. 它分成上传和下载两种情况 1)下载的progress事件属于XMLHttpRequest对 ...
- win7文件夹图标中多了一把小锁打不开文件夹怎么办?
win7文件夹图标中多了一把小锁打不开文件夹怎么办?解决办法一:右击目录→取得管理员权限!该方法适用于win7旗舰版.解决办法二:右击目录→属性→安全→高级→选择everyone→更改权限→勾上完全访 ...
- bootstrapt model 的多罩层,禁用罩层
选项 有一些选项可以用来定制模态窗口(Modal Window)的外观和感观,它们是通过 data 属性或 JavaScript 来传递的.下表列出了这些选项: 选项名称 类型/默认值 Data 属性 ...
- Android 如何解决数据库多线程锁的问题
防止多个线程又是读取又是写入 网上找到的方法: 对于这样的问题,解决的办法就是keep single sqlite connection,保持单个SqliteOpenHelper实例,同时对所有数据库 ...