Hibernate二级缓存简介

  在《Hibernate一级缓存——Session》中介绍了Session级别的一级缓存,例如,当如下的代码执行时,由于一级缓存的作用,只会发送一条select语句:

@Testpublic void testCache(){Employee employee1 = (Employee) session.get(Employee.class, 1);System.out.println(employee1);Employee employee2 = (Employee) session.get(Employee.class, 1);System.out.println(employee2);}

  现在,我们在两次加载代码之间,先关闭当前的session和事务,再重新开启一个session和事务,那么不难理解,由于开启了新的session,所以会打印两条select语句:

@Testpublic void testCache(){Employee employee1 = (Employee) session.get(Employee.class, 1);System.out.println(employee1);//提交事务,关sessiontransaction.commit();session.close();//开启一个新的session和事务session = sessionFactory.openSession();transaction = session.beginTransaction();Employee employee2 = (Employee) session.get(Employee.class, 1);System.out.println(employee2);}


  那么,有没有办法使就算session关闭,也能缓存employee对象的办法呢?这就是我们现在要介绍的,SessionFactory级别的,Hibernate二级缓存。
  
  缓存(Cache )是计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝,应用程序在运行时直接读写缓存中的数据,只在某些特定时刻按照缓存中的数据来同步更新数据存储源。缓存的物理介质通常是内存。
  
  Hibernate中提供了两个级别的缓存:
  1.第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存,即缓存只能被当前事务访问,每个事务都有独自的缓存。缓存的生命周期依赖于事务的生命周期,当事务结束时,缓存也就结束生命周期。在此范围下,缓存的介质是内存。这一级别的缓存是由hibernate管理的,一般情况下无须进行干预。
  2.第二级别的缓存是SessionFactory级别的缓存,它是属于进程范围的缓存。缓存被进程内的所有事务共享。这些事务有可能是并发访问缓存,因此必须对缓存采取必要的事务隔离机制。缓存的生命周期依赖于进程的生命周期,进程结束时,缓存也就结束了生命周期。进程范围的缓存可能会存放大量的数据,所以存放的介质可以是内存或硬盘。这一级别的缓存可以进行配置和更改,并且可以动态加载和卸载。
  
  SessionFactory 的缓存可以分为两类:
  内置缓存: Hibernate自带的,不可卸载。通常在Hibernate的初始化阶段,Hibernate会把映射元数据和预定义的SQL语句放到SessionFactory的缓存中,映射元数据是映射文件中数据的复制,而预定义SQL语句是Hibernate根据映射元数据推到出来的。该内置缓存是只读的。
  外置缓存(二级缓存):一个可配置的缓存插件。在默认情况下,SessionFactory不会启用这个缓存插件。外置缓存中的数据是数据库中数据的复制,外置缓存的物理介质可以是内存,也可以是硬盘。
  
  缓存的物理介质通常是内存,而永久性数据存储源的物理介质通常是硬盘或磁盘,应用程序读写内在的速度显然比读写硬盘的速度快,如果缓存中存放的数据量非常大,也会用硬盘作为缓存的物理介质。缓存的实现不仅需要作为物理介质的硬件,同时还需要用于管理缓存的并发访问和过期等策略的软件。因此,缓存是通过软件和硬件共同实现的。
  
  适合放入二级缓存中的数据:
  1.很少被修改;
  2.不是很重要的数据,允许出现偶尔的并发问题。
  
  不适合放入二级缓存中的数据:
  1.经常被修改;
  2.财务数据,绝对不允许出现并发问题;
  3.与其他应用程序共享的数据。
  
  二级缓存的并发访问策略:
  两个并发的事务同时访问持久层的缓存的相同数据时,也有可能出现各类并发问题。
  二级缓存可以设定以下4种类型的并发访问策略,每一种访问策略对应一种事务隔离级别。
  非严格读写(Nonstrict-read-write):不保证缓存与数据库种数据的一致性。提供read uncommitted事务隔离级别。对于极少被修改,而且允许脏读的数据,可以采用这种策略。
  读写型(Read-write):提供read committed事务隔离级别。对于经常读但是很少被修改的数据,可以采用这种隔离类型,它可以防止脏读。(通常选用的策略)
  事务型(Transactional):仅在受管理环境下适用。它提供了repeatable read的事务隔离级别。对于经常读,但是很少被修改的数据,可以采用这种隔离类型,它可以防止脏读和不可重复读。
  只读型(Read-Only):提供serializable事务隔离级别,对于从来不会修改的数据,可以采用这种访问策略,可以避免脏读,不可重复读和幻读。
  
  管理Hibernate的二级缓存:
  Hibernate的二级缓存是进程或者集群范围内的缓存。
  二级缓存是可配置的插件,Hibernate允许选用以下类型的缓存插件:
  EhCache:可作为进程范围的缓存,存放数据的物理介质可以是内存或硬盘,对Hibernate的查询缓存提供了支持。
  OSCache:可作为进程范围的缓存,存放数据的物理介质可以是内存或硬盘,提供了丰富的缓存数据过期策略,对Hibernate的查询缓存提供了支持。
  SwarmCache:可作为群集范围内的缓存,但不支持Hibernate的查询缓存。   JBossCache:可作为群集范围内的缓存,支持事务型并发访问策略,对Hibernate的查询缓存提供了支持。
  

使用Hibernate二级缓存的步骤

  
一、加入二级缓存的jar包及配置文件
  
1.加入jar包
  
  
2.添加配置文件ehcache.xml到src目录下

<ehcache><!-- Sets the path to the directory where cache .data files are created.If the path is a Java System Property it is replaced byits value in the running VM.The following properties are translated:user.home - User's home directoryuser.dir - User's current working directoryjava.io.tmpdir - Default temp file path --><diskStore path="java.io.tmpdir"/><!--Default Cache configuration. These will applied to caches programmatically created throughthe CacheManager.The following attributes are required for defaultCache:maxInMemory       - Sets the maximum number of objects that will be created in memoryeternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the elementis never expired.timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only usedif the element is not eternal. Idle time is now - last accessed timetimeToLiveSeconds - Sets the time to live for an element before it expires. Is only usedif the element is not eternal. TTL is now - creation timeoverflowToDisk    - Sets whether elements can overflow to disk when the in-memory cachehas reached the maxInMemory limit.--><defaultCache
        maxElementsInMemory="10000"eternal="false"timeToIdleSeconds="120"timeToLiveSeconds="120"overflowToDisk="true"/><!--Predefined caches.  Add your cache configuration settings here.If you do not have a configuration for your cache a WARNING will be issued when theCacheManager startsThe following attributes are required for defaultCache:name              - Sets the name of the cache. This is used to identify the cache. It must be unique.maxInMemory       - Sets the maximum number of objects that will be created in memoryeternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the elementis never expired.timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only usedif the element is not eternal. Idle time is now - last accessed timetimeToLiveSeconds - Sets the time to live for an element before it expires. Is only usedif the element is not eternal. TTL is now - creation timeoverflowToDisk    - Sets whether elements can overflow to disk when the in-memory cachehas reached the maxInMemory limit.--><!-- Sample cache named sampleCache1This cache contains a maximum in memory of 10000 elements, and will expirean element if it is idle for more than 5 minutes and lives for more than10 minutes.If there are more than 10000 elements it will overflow to thedisk cache, which in this configuration will go to wherever java.io.tmp isdefined on your system. On a standard Linux system this will be /tmp"--><cache name="sampleCache1"maxElementsInMemory="10000"eternal="false"timeToIdleSeconds="300"timeToLiveSeconds="600"overflowToDisk="true"/><!-- Sample cache named sampleCache2This cache contains 1000 elements. Elements will always be held in memory.They are not expired. --><cache name="sampleCache2"maxElementsInMemory="1000"eternal="true"timeToIdleSeconds="0"timeToLiveSeconds="0"overflowToDisk="false"/> --><!-- Place configuration for your caches following --></ehcache>

二、配置hibernate.cfg.xml
 
1.配置启用hibernate的二级缓存

<property name="cache.use_second_level_cache">true</property>

2.配置hibernate二级缓存使用的产品

<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

3.配置对哪些类(或属性)使用 hibernate 的二级缓存

第一种情况,类级别的二级缓存:(配置对Employee类使用二级缓存)

<class-cache usage="read-write" class="com.atguigu.hibernate.entities.Employee"/>

第二种情况,集合级别的二级缓存:(配置对Department类中的Employee集合属性emps使用二级缓存)

<collection-cache usage="read-write" collection="com.atguigu.hibernate.entities.Department.emps"/>

注意,当配置对集合属性使用二级缓存时,还需要对集合所属的类,集合中元素的类型使用二级缓存,例如,对于上述集合属性,则还需配置对Department类和Employee类使用二级缓存:(如果不对Employee类配置二级缓存,则会多出n条SQL语句,得不偿失。因为这种情况下缓存的是一个一个的employee的id,当要使用到employee对象时,需要再根据id一条一条地去数据库查询记录)

<class-cache usage="read-write" class="com.atguigu.hibernate.entities.Department"/>
<class-cache usage="read-write" class="com.atguigu.hibernate.entities.Employee"/>

另外,配置对哪些类(或属性)使用二级缓存,还可以在映射文件中配置,例如:
类级别(在class节点下):

<cache usage="read-write"/>

集合级别:(在department映射文件的set节点下)

<cache usage="read-write"/>

  现在,测试上面的testCache方法,只会打印一条select语句:
  
  对于集合的测试也是一样,只会打印两条select语句,一条用于查询department,一条用于查询employee:

@Testpublic void testCollectionSecondLevelCache(){Department dept = (Department) session.get(Department.class, 1);System.out.println(dept.getName());System.out.println(dept.getEmps().size()); transaction.commit();session.close();session = sessionFactory.openSession();transaction = session.beginTransaction();Department dept2 = (Department) session.get(Department.class, 1);System.out.println(dept2.getName());System.out.println(dept2.getEmps().size()); }

二级缓存配置文件

  下面使用一个修改过的二级缓存配置文件介绍其中各个属性的作用:

<ehcache><!-- Sets the path to the directory where cache .data files are created.If the path is a Java System Property it is replaced byits value in the running VM.The following properties are translated:user.home - User's home directoryuser.dir - User's current working directoryjava.io.tmpdir - Default temp file path --><!--  指定一个目录:当 EHCache 把数据写到硬盘上时, 将把数据写到这个目录下.-->     <diskStore path="d:\\tempDirectory"/><!--Default Cache configuration. These will applied to caches programmatically created throughthe CacheManager.The following attributes are required for defaultCache:maxInMemory       - Sets the maximum number of objects that will be created in memoryeternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the elementis never expired.timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only usedif the element is not eternal. Idle time is now - last accessed timetimeToLiveSeconds - Sets the time to live for an element before it expires. Is only usedif the element is not eternal. TTL is now - creation timeoverflowToDisk    - Sets whether elements can overflow to disk when the in-memory cachehas reached the maxInMemory limit.--><!--  设置缓存的默认数据过期策略 -->    <defaultCache
        maxElementsInMemory="10000"eternal="false"timeToIdleSeconds="120"timeToLiveSeconds="120"overflowToDisk="true"/><!--  设定具体的命名缓存的数据过期策略。每个命名缓存代表一个缓存区域缓存区域(region):一个具有名称的缓存块,可以给每一个缓存块设置不同的缓存策略。如果没有设置任何的缓存区域,则所有被缓存的对象,都将使用默认的缓存策略。即:<defaultCache.../>Hibernate 在不同的缓存区域保存不同的类/集合。对于类而言,区域的名称是类名。如:com.atguigu.domain.Customer对于集合而言,区域的名称是类名加属性名。如com.atguigu.domain.Customer.orders--><!--  name: 设置缓存的名字,它的取值为类的全限定名或类的集合的名字 maxElementsInMemory: 设置基于内存的缓存中可存放的对象最大数目 eternal: 设置对象是否为永久的, true表示永不过期,此时将忽略timeToIdleSeconds 和 timeToLiveSeconds属性; 默认值是false timeToIdleSeconds:设置对象空闲最长时间,以秒为单位, 超过这个时间,对象过期。当对象过期时,EHCache会把它从缓存中清除。如果此值为0,表示对象可以无限期地处于空闲状态。 timeToLiveSeconds:设置对象生存最长时间,超过这个时间,对象过期。如果此值为0,表示对象可以无限期地存在于缓存中. 该属性值必须大于或等于 timeToIdleSeconds 属性值 overflowToDisk:设置基于内存的缓存中的对象数目达到上限后,是否把溢出的对象写到基于硬盘的缓存中 --><cache name="com.atguigu.hibernate.entities.Employee"maxElementsInMemory="1"eternal="false"timeToIdleSeconds="300"timeToLiveSeconds="600"overflowToDisk="true"/><cache name="com.atguigu.hibernate.entities.Department.emps"maxElementsInMemory="1000"eternal="true"timeToIdleSeconds="0"timeToLiveSeconds="0"overflowToDisk="false"/></ehcache>

查询缓存

  对于经常使用的查询语句,如果启用了查询缓存,当第一次执行查询语句时,Hibernate会把查询结果存放在查询缓存中,以后再次执行该查询语句时,只需从缓存中获得查询结果,从而提高查询性能。
  默认情况下,Hibernate设置的缓存对HQL和QBC查询是无效的,但可以通过以下步骤使其有效:
  1.配置二级缓存,因为查询缓存依赖于二级缓存.
  2.在hibernate配置文件中声明开启查询缓存。

<property name="cache.use_query_cache">true</property>

  3.调用Query或者Criteria的setCachable(true)。
  
例如,在没有配置查询缓存的情况下,下面的代码会打印两条select语句:

@Testpublic void testQueryCache(){Query query = session.createQuery("FROM Employee");List<Employee> emps = query.list();System.out.println(emps.size());emps = query.list();System.out.println(emps.size());}


  
  进行了相关配置之后,并且在方法中设置query.setCacheable(true);则只会打印一条select语句:

@Testpublic void testQueryCache(){Query query = session.createQuery("FROM Employee");query.setCacheable(true);List<Employee> emps = query.list();System.out.println(emps.size());emps = query.list();System.out.println(emps.size());}

  查询缓存适用于如下场合:
  1.应用程序运行时经常使用查询语句
  2.很少对与查询语句检索到的数据进行插入,删除或更新操作

时间戳缓存区域

  时间戳缓存区域存放了对于查询结果相关的表进行插入,更新或者删除操作的时间戳。Hibernate通过时间戳缓存区域来判断被缓存的查询结果是否过期,其运行过程如下:
  T1时刻执行查询操作,把结果存放在QueryCache区域,记录该区域的时间戳为T1;
  T2时刻(可能在T1之前,也可能在T1之后)对查询结果相关的表进行更新操作,Hibernate把T2时刻存放在UpdateTimestampCache区域。
  T3时刻(在T1,T2之后)执行查询结果前,先比较QueryCache区域的时间戳和UpdateTimestampCache区域的时间戳。若T2>T1,则丢弃原先存放在QueryCache区域的查询结果,重新到数据库中查询数据并放入QueryCache区域;若T2

@Testpublic void testUpdateTimeStampCache(){Query query = session.createQuery("FROM Employee");query.setCacheable(true);List<Employee> emps = query.list();System.out.println(emps.size());Employee employee = (Employee) session.get(Employee.class, 1);employee.setSalary(30000);emps = query.list();System.out.println(emps.size());}

  在第二次查询的时候,会重新用select去数据库中查找最新的记录。
  

Query接口的iterate()方法

  Query的list方法返回实体类对应表的所有字段,而Query的iterate方法仅返回数据包的ID字段。当使用了iterate方法,然后遍历访问结果集时,先到Session缓存及二级缓存中查看是否存在特定OID的对象,如果存在,直接返回,否则就通过相应的SQL SELECT语句到数据库中查找特定的记录。
  在大多数情况下,应该考虑使用list方法执行查询操作,iterate方法仅在下述情况下可以稍微提高查询性能:
  1.要查询的数据表中包含大量字段;
  2.启用了二级缓存,且二级缓存中可能已经包含了待查询的对象。

Hibernate二级缓存——SessionFactory相关推荐

  1. Hibernate EHCache - Hibernate二级缓存

    Hibernate EHCache - Hibernate二级缓存 欢迎使用Hibernate二级缓存示例教程.今天我们将研究Hibernate EHCache,它是最受欢迎的Hibernate二级缓 ...

  2. Hibernate二级缓存问题

    相关概念和定义 1.缓存的意义 把一些不常修改,但是又经常用的数据存放到内存中,这样能减少与数据库的交互,提升程序的性能 2.Hibernate中提供了两级缓存: 第一级别的缓存是Session级别的 ...

  3. HibernateEHCache –Hibernate二级缓存

    Welcome to the Hibernate Second Level Cache Example Tutorial. Today we will look into Hibernate EHCa ...

  4. hibernate二级缓存(三) 自定义实现一个简单的hibernate二级缓存

    hibernate二级缓存(三) 自定义实现一个简单的hibernate二级缓存 前面我们已经提及过hibernate内部为二级缓存的扩展做了很多的实现.我们只需要实现RegionFactoryTem ...

  5. Hibernate二级缓存详解(转)

    Hibernate二级缓存详解(转) 本文转载 http://www.blogjava.net/supercrsky/articles/238580.html 与Session相对的是,Session ...

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

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

  7. Hibernate二级缓存攻略

    Hibernate二级缓存攻略 很多人对二级缓存都不太了解,或者是有错误的认识,我一直想写一篇文章介绍一下hibernate的二级缓存的,今天终于忍不住了. fi9-DVR]   我的经验主要来自hi ...

  8. Hibernate二级缓存的使用

    1启用Hibernate二级缓存 Hibernate二级缓存分为两部分,class缓存和查询缓存,其获取对象的方式有所不同,但两者也有联系,查询缓存必须以class缓存为基础才能起作用,否则只会使效率 ...

  9. Hibernate 二级缓存使用

    1启用Hibernate二级缓存 Hibernate二级缓存分为两部分,class缓存和查询缓存,其获取对象的方式有所不同,但两者也有联系,查询缓存必须以class缓存为基础才能起作用,否则只会使效率 ...

  10. 配置Hibernate二级缓存步骤

    配置Hibernate二级缓存步骤: 加入二级缓存的jar包及配置文件 jar包位置:hibernate-release-4.1.8.Final\lib\optional\ehcache下所有jar包 ...

最新文章

  1. 设计模式 -- 中介者设计模式 (Mediator Pattern)
  2. Pull和SAX解析XML,以解析中国省市列表为例子
  3. Action profile: ZAVADDR和ZAVPERS
  4. 「协方差」与「相关系数」的概念
  5. cat3 utp是不是网线_小科普 | 网线也有高低?聊聊网线的差别
  6. $ajax 筛选某个属性,jQuery
  7. Python中提供的各种队列结构
  8. 区块链研究生专业_滁州区块链平台技术开发专业软件公司
  9. 北京大学生物信息学(8)
  10. 异常处理和代码复用在python自动化运维中的使用(eNSP模拟器)
  11. python linux开发_python之Linux开发环境安装
  12. 微服务、容器、云原生、Kubernetes、SOA、PaaS平台、Devops 之间的关系
  13. 【全套完结】数字信号处理----全套Matlab实验报告【建议保存】
  14. 喧嚣过后,揭秘《咪蒙教你月薪5万》背后的真相
  15. 阿里java类注释模板_向IDE导入阿里编码规约格式化模板和注释模板
  16. 第3章第11节:如何将众多图片制作成照片墙并作为幻灯片的背景 [PowerPoint精美幻灯片实战教程]
  17. Python数据 分析微信朋友圈
  18. 推荐25种自媒体运营必备工具 (建议收藏)
  19. 外贸业务员每天必做的事情!
  20. 海信、索尼“圈层化”、美的、小天鹅奔向“拼多多”,家电品牌谋新路

热门文章

  1. 计算机械效率的公式四种,物理计算公式;
  2. 基于单片机的人体心率脉搏检测系统
  3. 电影推荐系统kaggle
  4. 消防巡检控制器,消防泵巡检控制柜专用元件
  5. html5+前端脸部识别采集,前端人脸识别框架Tracking.js
  6. 采购订单模板_金蝶KIS商贸版(采购模块)常见问题汇总
  7. 移动机顶盒cm211-1 刷机
  8. 大型工业互联网项目(5000w+)投标复盘
  9. 乐优商城服务器部署_黑马乐优商城19天(全)+源码+配套笔记
  10. Robocode学习Java