Hibernate-二级缓存 sessionFactory
Hibernate 二级缓存
二级缓存需要sessionFactory来管理,它是进初级的缓存,所有人都可以使用,它是共享的。
当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。
二级缓存比较复杂,一般用第三方产品。
hibernate提供了一个简单实现,用Hashtable做的,只能作为我们的测试使用,商用还是需要第三方产品。
使用缓存,肯定是长时间不改变的数据,如果经常变化的数据放到缓存里就没有太大意义了。因为经常变化,还是需要经常到数据库里查询,那就没有必要用缓存了。
hibernate做了一些优化,和一些第三方的缓存产品做了集成。
在默认情况下,Hibernate会使用EHCache作为二级缓存组件。但是,可以通过设置 ibernate.cache.provider_class属性,指定其他的缓存策略,该缓存策略必须实现 org.hibernate.cache.CacheProvider接口。
通过实现org.hibernate.cache.CacheProvider接口可以提供对不同二级缓存组件的支持。
Hibernate内置支持的二级缓存组件如表
组件 |
Provider类 |
类型 |
集群 |
查询缓存 |
Hashtable |
org.hibernate.cache.HashtableCacheProvider |
内存 |
不支持 |
支持 |
EHCache |
org.hibernate.cache.EhCacheProvider |
内存,硬盘 |
最新支持 |
支持 |
OSCache |
org.hibernate.cache.OSCacheProvider |
内存,硬盘 |
不支持 |
支持 |
SwarmCache |
org.hibernate.cache.SwarmCacheProvider |
集群 |
支持 |
不支持 |
JBoss TreeCache |
org.hibernate.cache.TreeCacheProvider |
集群 |
支持 |
支持 |
这里测试以EHCache继承实例
EHCache的jar文件在hibernate的lib里,我们还需要设置一系列的缓存使用策略,需要一个配置文件ehcache.xml来配置。
配置ehcache.xml(这个文件放在类路径下)
//默认配置,所有的类都遵循这个配置
<defaultCache
//缓存里可以放10000个对象
maxElementsInMemory="10000"
//过不过期,如果是true就是永远不过期
eternal="false"
//一个对象被访问后多长时间还没有访问就失效(120秒还没有再次访问就失效)
timeToIdleSeconds="120"
//对象存活时间(120秒),如果设置永不过期,这个就没有必要设了
timeToLiveSeconds="120"
//溢出的问题,如果设成true,缓存里超过10000个对象就保存到磁盘里
overflowToDisk="true"
/>
也可以对某个对象单独配置:
<cache name="com.bjpowernode.hibernate.Student" maxElementsInMemory="100" eternal="false" timeToIdleSeconds="10000" timeToLiveSeconds="10000" overflowToDisk="true" />
hibernate需要配置引入插件
hibernate.cfg.xml配置文件配置缓存,让hibernate知道我们使用的是那个二级缓存。
<!-- 配置缓存提供商 --> <property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<!-- 启用二级缓存,这也是它的默认配置,启用二级缓存的配置可以不写的,因为默认就是true开启二级缓存。 --> <property name="hibernate.cache.use_second_level_cache">
true
</property>
hibernate需要制定哪些使用二级缓存
必须还手动指定那些实体类的对象放到缓存里在hibernate.cfg.xml里:
//在<sessionfactory>标签里,在<mapping>标签后配置 <class-cache class="com.bjpowernode.hibernate.Student" usage="read-only"/>
或者在实体类映射文件.hbm.xml里:
//在<class>标签里,<id>标签前配置 <cache usage="read-only"/>
usage属性表示使用缓存的策略,一般优先使用read-only,表示如果这个数据放到缓存里了,则不允许修改,如果修改就会报错。这就要注意我们放入缓存的数据不允许修改。因为放缓存里的数据经常修改,也就没有必要放到缓存里。
二级缓存策略
只读缓存(read-only)
表示如果这个数据放到缓存里了,则不允许修改,如果修改就会报错
使用read-only策略效率好,因为不能改缓存。但是可能会出现脏数据的问题,这个问题解决方法只能依赖缓存的超时,比如上面我们设置了超时为120秒,120后就可以对缓存里对象进行修改,而在120秒之内访问这个对象可能会查询脏数据的问题,因为我们修改对象后数据库里改变了,而缓存却不能改变,这样造成数据不同步,也就是脏数据的问题。
读/写缓存(read-write)
当持久对象发生变化,缓存里就会跟着变化,数据库中也改变了。这种方式需要加解锁,效率要比第一种慢
则是最常用的两种策略
不严格的读/写缓存(nonstrict-read-write)
如果程序偶尔需要更新数据(也就是说,出现两个事务同时更新同一个条目的现象很不常见),也不需要十分严格的事务隔离,可能适用nonstrict-read-write缓存。
对于极少被修改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。
事务缓存(transactional)
transactional缓存策略提供了对全事务的缓存,仅仅在受管理环境中使用。它提供了Repeatable Read事务隔离级别。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读和不可重复读这类的并发问题。
在上面所介绍的隔离级别中,事务型并发访问策略的隔离级别最高,然后依次是读/写型和不严格读写型,只读型的隔离级别最低。事务的隔离级别越高,并发性能就越低。
二级缓存实例
当两个session分别调用load方法查询相同的数据,第二个session的load方法还是发了sql语句到数据库查询数据,这是因为一级缓存只在当前session中共享,也就是说一级缓存不能跨session访问。
那么二级缓存呢?
//开启二级缓存,二级缓存是进程级的缓存,可以共享 //两个session分别调用load方法查询相同的实体对象 try {
session = HibernateUtils.getSession();
session.beginTransaction();
Student student = (Student)session.load(Student.class, 1);
System.out.println("student.name=" + student.getName());
session.getTransaction().commit(); }catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback(); }finally {
HibernateUtils.closeSession(session); } try {
session = HibernateUtils.getSession();
session.beginTransaction();
Student student = (Student)session.load(Student.class, 1);
//不会发出查询语句,因为配置二级缓存,session可以共享二级缓存中的数据
//二级缓存是进程级的缓存
System.out.println("student.name=" + student.getName());
session.getTransaction().commit(); }catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback(); }finally {
HibernateUtils.closeSession(session); }
如果开启了二级缓存,那么第二个session调用的load方法查询第一次查询的数据,是不会发出sql语句查询数据库的,而是去二级缓存中取数据。
开启二级缓存后在次执行
注意:二级缓存必须让sessionfactory管理,让sessionfactory来清除二级缓存。
sessionFactory.evict(Student.class);//清除二级缓存中所有student对象,sessionFactory.evict(Student.class,1);//清除二级缓存中id为1的student对象。
如果在第一个session调用load或get方法查询数据后,把二级缓存清除了,那么第二个session调用load或get方法查询相同的数据时,还是会发出sql语句查询数据库的,因为缓存里没有数据只能到数据库里查询。
我们查询数据后会默认自动的放到二级和一级缓存里,如果我们想查询的数据不放到缓存里,也是可以的。也就是说我们可以控制一级缓存和二级缓存的交换。
session.setCacheMode(CacheMode.IGNORE);禁止将一级缓存中的数据往二级缓存里放。
还是用上面代码测试,在第一个session调用load方法前,执行session.setCacheMode(CacheMode.IGNORE);这样load方法查询的数据不会放到二级缓存里。那么第二个session执行load方法查询相同的数据,会发出sql语句到数据库中查询,因为二级缓存里没有数据,一级缓存因为不同的session不能共享,所以只能到数据库里查询。
上面我们讲过大批量的数据添加时可能会出现溢出,解决办法是每当天就20个对象后就清理一次一级缓存。如果我们使用了二级缓存,光清理一级缓存是不够的,还要禁止一二级缓存交互,在save方法前调用session.setCacheMode(CacheMode.IGNORE)。
二级缓存也不会存放普通属性的查询数据,这和一级缓存是一样的,只存放实体对象。session级的缓存对性能的提高没有太大的意义,因为生命周期太短了。
Hibernate-二级缓存 sessionFactory的更多相关文章
- hibernate笔记--缓存机制之 二级缓存(sessionFactory)和查询缓存
二级缓存(sessionFactory): Hibernate的二级缓存由SessionFactory对象管理,是应用级别的缓存.它可以缓存整个应用的持久化对象,所以又称为“SessionFactor ...
- Hibernate ——二级缓存
一.Hibernate 二级缓存 1.Hibernate 二级缓存是 SessionFactory 级别的缓存. 2.二级缓存分为两类: (1)Hibernate内置二级缓存 (2)外置缓存,可配置的 ...
- Hibernate 二级缓存 总结整理(转)
和<Hibernate 关系映射 收集.总结整理> 一样,本篇文章也是我很早之前收集.总结整理的,在此也发上来 希望对大家有用.因为是很早之前写的,不当之处请指正. 1.缓存:缓存是什么, ...
- Hibernate(十六):Hibernate二级缓存
Hibernate缓存 缓存(Cache):计算机领域非常通用的概念.它介于应用程序和永久性数据存储源(如磁盘上的文件或者数据库)之间,起作用是降低应用程序直接读取永久性数据存储源的频率,从而提高应用 ...
- hibernate二级缓存demo2
@Test public void hello3(){ Session session=sessionFactory.openSession(); List list = session.create ...
- hibernate二级缓存整合
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http:// ...
- ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存
ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存 hibernate : Hibernate是一个持久层框架,经常访问物理数据库 ...
- js相关(easyUI),触发器,ant,jbpm,hibernate二级缓存ehcache,Javamail,Lucene,jqplot,WebService,regex,struts2,oracle表空间
*********************************************js相关********************************************* // 在指 ...
- hibernate二级缓存ehcache hibernate配置详解
<!-----------------hibernate二级缓存ehcache------------------------->hibernate配置 <prop key=&quo ...
- Hibernate 二级缓存配置
详见:https://www.cnblogs.com/Junsept/p/7324981.html Hibernate的cache管理: Cache就是缓存,它往往是提高系统性能的最重要手段,对数据起 ...
随机推荐
- 1.素数判定(如何输出\n,\t,不用关键字冲突)
题目描述 Description 质数又称素数.指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数整除的数. 素数在数论中有着很重要的地位.比1大但不是素数的数称为合数.1和0既非素数也 ...
- css中table tr:nth-child(even)改变tr背景颜色: IE7,8无效
例如: .my_table tr:nth-child(even){ background:#E6EDF5; } .my_table tr:nth-child(odd){ background:#F0F ...
- man 在线手册
http://man7.org/linux/man-pages/man3/fwrite.3.html
- K2与OData和Swagger的集成
最近K2陆续发布了一些好消息,从与Box的集成到今年取得的融资.这儿还有一个:K2近期宣布获得了DData和Swagger REST的支持,保障K2 Appit和Blackpearl的用户能建立基于工 ...
- Python高手之路【八】python基础之requests模块
1.Requests模块说明 Requests 是使用 Apache2 Licensed 许可证的 HTTP 库.用 Python 编写,真正的为人类着想. Python 标准库中的 urllib2 ...
- 装了个干净的win7
lanny的电脑基本信息 我的电脑 联想 ThinkPad T450s 笔记本电脑 操作系统 Windows 旗舰版 64位 主显卡 集成显卡 IE浏览器 版本号 8.0 基本硬件展示 处理器 英特尔 ...
- Jdeveloper 太慢 slowly
https://blogs.oracle.com/shay/entry/is_your_jdeveloper_slow_it_sho http://bexhuff.com/2012/09/jdevel ...
- 在opencv3中实现机器学习之:利用svm(支持向量机)分类
svm分类算法在opencv3中有了很大的变动,取消了CvSVMParams这个类,因此在参数设定上会有些改变. opencv中的svm分类代码,来源于libsvm. #include "s ...
- [CareerCup] 8.8 Othello Game 黑白棋游戏
8.8 Othello is played as follows: Each Othello piece is white on one side and black on the other. Wh ...
- [CareerCup] 14.6 CircularArray 环形数组
14.6 Implement a CircularArray class that supports an array-like data structure which can be efficie ...