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的更多相关文章

  1. hibernate笔记--缓存机制之 二级缓存(sessionFactory)和查询缓存

    二级缓存(sessionFactory): Hibernate的二级缓存由SessionFactory对象管理,是应用级别的缓存.它可以缓存整个应用的持久化对象,所以又称为“SessionFactor ...

  2. Hibernate ——二级缓存

    一.Hibernate 二级缓存 1.Hibernate 二级缓存是 SessionFactory 级别的缓存. 2.二级缓存分为两类: (1)Hibernate内置二级缓存 (2)外置缓存,可配置的 ...

  3. Hibernate 二级缓存 总结整理(转)

    和<Hibernate 关系映射 收集.总结整理> 一样,本篇文章也是我很早之前收集.总结整理的,在此也发上来 希望对大家有用.因为是很早之前写的,不当之处请指正. 1.缓存:缓存是什么, ...

  4. Hibernate(十六):Hibernate二级缓存

    Hibernate缓存 缓存(Cache):计算机领域非常通用的概念.它介于应用程序和永久性数据存储源(如磁盘上的文件或者数据库)之间,起作用是降低应用程序直接读取永久性数据存储源的频率,从而提高应用 ...

  5. hibernate二级缓存demo2

    @Test public void hello3(){ Session session=sessionFactory.openSession(); List list = session.create ...

  6. hibernate二级缓存整合

    <?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http:// ...

  7. ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存

    ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存 hibernate  : Hibernate是一个持久层框架,经常访问物理数据库 ...

  8. js相关(easyUI),触发器,ant,jbpm,hibernate二级缓存ehcache,Javamail,Lucene,jqplot,WebService,regex,struts2,oracle表空间

    *********************************************js相关********************************************* // 在指 ...

  9. hibernate二级缓存ehcache hibernate配置详解

    <!-----------------hibernate二级缓存ehcache------------------------->hibernate配置 <prop key=&quo ...

  10. Hibernate 二级缓存配置

    详见:https://www.cnblogs.com/Junsept/p/7324981.html Hibernate的cache管理: Cache就是缓存,它往往是提高系统性能的最重要手段,对数据起 ...

随机推荐

  1. 1.素数判定(如何输出\n,\t,不用关键字冲突)

    题目描述 Description 质数又称素数.指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数整除的数. 素数在数论中有着很重要的地位.比1大但不是素数的数称为合数.1和0既非素数也 ...

  2. 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 ...

  3. man 在线手册

    http://man7.org/linux/man-pages/man3/fwrite.3.html

  4. K2与OData和Swagger的集成

    最近K2陆续发布了一些好消息,从与Box的集成到今年取得的融资.这儿还有一个:K2近期宣布获得了DData和Swagger REST的支持,保障K2 Appit和Blackpearl的用户能建立基于工 ...

  5. Python高手之路【八】python基础之requests模块

    1.Requests模块说明 Requests 是使用 Apache2 Licensed 许可证的 HTTP 库.用 Python 编写,真正的为人类着想. Python 标准库中的 urllib2  ...

  6. 装了个干净的win7

    lanny的电脑基本信息 我的电脑 联想 ThinkPad T450s 笔记本电脑 操作系统 Windows 旗舰版 64位 主显卡 集成显卡 IE浏览器 版本号 8.0 基本硬件展示 处理器 英特尔 ...

  7. Jdeveloper 太慢 slowly

    https://blogs.oracle.com/shay/entry/is_your_jdeveloper_slow_it_sho http://bexhuff.com/2012/09/jdevel ...

  8. 在opencv3中实现机器学习之:利用svm(支持向量机)分类

    svm分类算法在opencv3中有了很大的变动,取消了CvSVMParams这个类,因此在参数设定上会有些改变. opencv中的svm分类代码,来源于libsvm. #include "s ...

  9. [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 ...

  10. [CareerCup] 14.6 CircularArray 环形数组

    14.6 Implement a CircularArray class that supports an array-like data structure which can be efficie ...