当前位置: 首页 > news >正文

Hibernate(十六):Hibernate二级缓存

  • Hibernate缓存

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

Hibernate中提供了两个级别的缓存

1)第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存。这一级别的缓存由hibernate管理。

测试函数1:Hibernate一级缓存示例

1     @Test
2     public void testHibernateCacheLevel1() {
3         Department depart0 = (Department) session.get(Department.class, 1);
4         System.out.println(depart0);
5         
6         Department depart1 = (Department) session.get(Department.class, 1);
7         System.out.println(depart1);
8     }
View Code

执行sql及结果:

 1 Hibernate: 
 2     select
 3         department0_.ID as ID1_0_0_,
 4         department0_.NAME as NAME2_0_0_ 
 5     from
 6         DX_DEPARTMENT department0_ 
 7     where
 8         department0_.ID=?
 9 Department [id=1, name=开发部门]
10 
11 Department [id=1, name=开发部门]
View Code

测试函数2:Hibernate一级缓存是事务级别证明

 1     @Test
 2     public void testHibernateCacheLevel1_Transaction() {
 3         Department depart0 = (Department) session.get(Department.class, 1);
 4         System.out.println(depart0);
 5         
 6         transaction.commit();
 7         session.close();
 8         session = sessionFactory.getCurrentSession();
 9         transaction = session.beginTransaction();
10         
11         Department depart1 = (Department) session.get(Department.class, 1);
12         System.out.println(depart1);
13     }
View Code

执行sql及结果:

 1 Hibernate: 
 2     select
 3         department0_.ID as ID1_0_0_,
 4         department0_.NAME as NAME2_0_0_ 
 5     from
 6         DX_DEPARTMENT department0_ 
 7     where
 8         department0_.ID=?
 9 Department [id=1, name=开发部门]
10 
11 Hibernate: 
12     select
13         department0_.ID as ID1_0_0_,
14         department0_.NAME as NAME2_0_0_ 
15     from
16         DX_DEPARTMENT department0_ 
17     where
18         department0_.ID=?
19 Department [id=1, name=开发部门]
View Code

备注:

本章节所涉及到的demo工程是基于Hibernate(十二):HQL查询(一)所创建的工程基础上进行测试。

2)第二级别的缓存是SesssionFactory级别的缓存,它是属于进程范围的缓存。

  • SessionFactory级别的缓存

SesssionFactory的缓存可以分为两类

1)内置缓存:Hibernate自带的,不可卸载。通常在Hibernate的初始化阶段,Hibernate会把映射元数据和预定义的SQL语句放到SessionFactory的缓存中,映射元数据是映射文件中数据(.hbm.xml文件中的数据)的赋值,该内置缓存是只读的。

2)外置缓存(二级缓存):一个可配置的缓存插件。在默认情况下,SessionFactory不会启用这个缓存插件。外置缓存中的数据是数据库数据的复制,外置缓存的物理介质可以是内存或硬盘。

  • Hibernate二级缓存的适用范围

1)适合放入二级缓存的数据:

  很少被修改

  不是很重要的数据,允许出现偶尔的并发问题

2)不适合放入二级缓存中的数据

  经常被修改

  财务数据,绝对不允许出现并发问题

  与其他应用程序共享的数据

  • Hibernate二级缓存架构图

  • 二级缓存的并发访问策略

1)两个并发的事务同时访问持久层的缓存的相同数据时,也有可能出现各类并发问题。

2)二级缓存可以设定以下4种类型的并发访问策略,每一种访问策略对应一种事务隔离界别:

  √ 非严格读写(Nonstrict-read-write):不保证缓存与数据库中数据一致性。提供Read Uncommited 事务隔离级别,对于极少被修改,而且允许脏读的数据可以采用该策略。

  √ 读写型(Read-write):提供Read Commited事务隔离级别。对于经常读但是很少被修改的数据,可以采用该隔离类型,因为它可以防止脏读。

  √ 事务型(Transactional):仅在受管理环境下适用,它提供了Repeateable Read事务隔离级别。对于经常读但很少被修改的数据,可以采用这种隔离策略,应为它可以防止脏读和不可重复读。

  √ 只读型(Read-Only):提供Serializable数据隔离级别,对于从来不会被修改的数据,可以采用这种访问策略。

  • 管理Hibernate的二级缓存

1)Hibernate的二级缓存是进程或集群分为内的缓存

2)二级缓存是可配置的插件,Hibernate允许选用选用以下类型的缓存插件:

  √ EHCache:可作为进程范围内存的缓存,存放数据的物理介质可以使用内存或磁盘,对Hibernate查询缓存提供了支持。

  √ OpenSymphony OSCahce:可以作为内存范围内的缓存,存放数据的物理介质可以使用内存或硬盘,提供了丰富的缓存数据过期策略,对Hibernate的查询缓存提供了支持。

  √ SwarmCache:可以作为集群范围内的缓存,但不支持Hibernate的查询缓存。

  √ JBoosCache:可作为集群范围内的缓存,支持Hibernate的查询缓存。

4种缓存插件支持的并发访问策略:

  • EHCache的使用:

步骤一:添加EHCache需要的jar包

找到hibernate开发路径\hibernate-release-5.2.9.Final\lib\optional\ehcache\下的所有jar,导入到工程。

步骤二:拷贝ehcache.xml文件到src下

拷贝hibernate-release-5.2.9.Final\project\etc\ehcache.xml文件到src下

步骤三:通过配置hibernate.cfg.xml文件启用hibernate二级缓存,并指定二级缓存的实现类

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6     <session-factory>
 7             。。。
 8         <!-- 启用二级缓存 -->
 9         <property name="hibernate.cache.use_second_level_cache">true</property>
10         <!-- 配置二级缓存使用的插件 -->
11         <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
12             。。。
13     </session-factory>
14 </hibernate-configuration>

步骤四:在hibernate.cfg.xml或者Department.hbm.xml中配置,针对Department启用二级缓存。

1)通过配置hibernate.cfg.xml启用Department类的二级缓存

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        。。。        
        <!-- 启用二级缓存 -->
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <!-- 配置二级缓存使用的插件 -->
        <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

        <mapping resource="com/dx/hibernate09/hql01/Department.hbm.xml" />
        <mapping resource="com/dx/hibernate09/hql01/Employee.hbm.xml" />
                
        <class-cache usage="read-write" class="com.dx.hibernate09.hql01.Department"/>
    </session-factory>
</hibernate-configuration>

2)通过配置Department.hbm.xml来启用Department类的二级缓存

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <!-- Generated 2017-6-9 23:13:49 by Hibernate Tools 3.5.0.Final -->
 5 <hibernate-mapping>
 6     <class name="com.dx.hibernate09.hql01.Department" table="DX_DEPARTMENT">
 7         <cache usage="read-write" />
 8 
 9         <id name="id" type="java.lang.Integer">
10             <column name="ID" />
11             <generator class="native" />
12         </id>
13         <property name="name" type="java.lang.String">
14             <column name="NAME" />
15         </property>
16 
17         <set name="employees" table="DX_EMPLOYEE" inverse="true" lazy="true">
18             <key>
19                 <column name="DEPARTMENT_ID" />
20             </key>
21             <one-to-many class="com.dx.hibernate09.hql01.Employee" />
22         </set>
23     </class>
24 </hibernate-mapping>

测试代码:

 1     @Test
 2     public void testHibernateCacheLevel1_Transaction() {
 3         Department depart0 = (Department) session.get(Department.class, 1);
 4         System.out.println(depart0);
 5         
 6         transaction.commit();
 7         session.close();
 8         session = sessionFactory.getCurrentSession();
 9         transaction = session.beginTransaction();
10         
11         Department depart1 = (Department) session.get(Department.class, 1);
12         System.out.println(depart1);
13     }

执行sql及结果:

 1 Hibernate: 
 2     select
 3         department0_.ID as ID1_0_0_,
 4         department0_.NAME as NAME2_0_0_ 
 5     from
 6         DX_DEPARTMENT department0_ 
 7     where
 8         department0_.ID=?
 9 Department [id=1, name=开发部门]
10 
11 Department [id=1, name=开发部门]

 

相关文章:

  • 函数计算-触发OSS来处理图片加水印和大小裁剪
  • 【Android Studio探索之路系列】之六:Android Studio加入依赖
  • 重装系统再也不用担心桌面文件丢失了
  • Node.js转化GBK编码 - iconv-lite
  • 初学makefile
  • SSM框架搭架
  • Maven工程配置代码覆盖工具Jacoco
  • linux进程D状态_转
  • MongoDB 聚合查询
  • Android组件 - 收藏集 - 掘金
  • java统计abacbacdadbc中的每个字母出现的次数,输出格式是:a(4)b(3)c(3)d(2)
  • ASP.NET Core 简单实现七牛图片上传(FormData 和 Base64)
  • docker 镜像(四)
  • 笨方法使用Kubernetes实现持续交付
  • You need to use a Theme.AppCompat theme (or descendant) with this activity
  • “大数据应用场景”之隔壁老王(连载四)
  • 10个最佳ES6特性 ES7与ES8的特性
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • const let
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • leetcode-27. Remove Element
  • MySQL主从复制读写分离及奇怪的问题
  • Node 版本管理
  • React as a UI Runtime(五、列表)
  • Redis中的lru算法实现
  • Spark学习笔记之相关记录
  • v-if和v-for连用出现的问题
  • vue-router 实现分析
  • Vue小说阅读器(仿追书神器)
  • 阿里云购买磁盘后挂载
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • Spring Batch JSON 支持
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • ###C语言程序设计-----C语言学习(6)#
  • $.ajax()
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (4.10~4.16)
  • (八)Flask之app.route装饰器函数的参数
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (十八)三元表达式和列表解析
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .NET Core 中插件式开发实现
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • /bin/rm: 参数列表过长"的解决办法
  • /etc/sudoers (root权限管理)
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)