• Hibernate缓存

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

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

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

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

     @Test
public void testHibernateCacheLevel1() {
Department depart0 = (Department) session.get(Department.class, 1);
System.out.println(depart0); Department depart1 = (Department) session.get(Department.class, 1);
System.out.println(depart1);
}

执行sql及结果:

 Hibernate:
select
department0_.ID as ID1_0_0_,
department0_.NAME as NAME2_0_0_
from
DX_DEPARTMENT department0_
where
department0_.ID=?
Department [id=1, name=开发部门] Department [id=1, name=开发部门]

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

     @Test
public void testHibernateCacheLevel1_Transaction() {
Department depart0 = (Department) session.get(Department.class, 1);
System.out.println(depart0); transaction.commit();
session.close();
session = sessionFactory.getCurrentSession();
transaction = session.beginTransaction(); Department depart1 = (Department) session.get(Department.class, 1);
System.out.println(depart1);
}

执行sql及结果:

 Hibernate:
select
department0_.ID as ID1_0_0_,
department0_.NAME as NAME2_0_0_
from
DX_DEPARTMENT department0_
where
department0_.ID=?
Department [id=1, name=开发部门] Hibernate:
select
department0_.ID as ID1_0_0_,
department0_.NAME as NAME2_0_0_
from
DX_DEPARTMENT department0_
where
department0_.ID=?
Department [id=1, name=开发部门]

备注:

本章节所涉及到的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二级缓存,并指定二级缓存的实现类

 <?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>
。。。
</session-factory>
</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类的二级缓存

 <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-6-9 23:13:49 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.dx.hibernate09.hql01.Department" table="DX_DEPARTMENT">
<cache usage="read-write" /> <id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property> <set name="employees" table="DX_EMPLOYEE" inverse="true" lazy="true">
<key>
<column name="DEPARTMENT_ID" />
</key>
<one-to-many class="com.dx.hibernate09.hql01.Employee" />
</set>
</class>
</hibernate-mapping>

测试代码:

     @Test
public void testHibernateCacheLevel1_Transaction() {
Department depart0 = (Department) session.get(Department.class, 1);
System.out.println(depart0); transaction.commit();
session.close();
session = sessionFactory.getCurrentSession();
transaction = session.beginTransaction(); Department depart1 = (Department) session.get(Department.class, 1);
System.out.println(depart1);
}

执行sql及结果:

 Hibernate:
select
department0_.ID as ID1_0_0_,
department0_.NAME as NAME2_0_0_
from
DX_DEPARTMENT department0_
where
department0_.ID=?
Department [id=1, name=开发部门] Department [id=1, name=开发部门]

Hibernate(十六):Hibernate二级缓存的更多相关文章

  1. Hibernate的查询,二级缓存,连接池

    Hibernate的查询,二级缓存,连接池 1.Hibernate查询数据 Hibernate中的查询方法有5中: 1.1.Get/Load主键查询 使用get或者load方法来查询,两者之间的区别在 ...

  2. J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用

    J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用   spring 中获得由spring所配置的hibernate的操作对象,然后利用此对象进行,保存,修 ...

  3. hibernate框架学习之二级缓存

    缓存的意义 l应用程序中使用的数据均保存在永久性存储介质之上,当应用程序需要使用数据时,从永久介质上进行获取.缓存是介于应用程序与永久性存储介质之间的一块数据存储区域.利用缓存,应用程序可以将使用的数 ...

  4. hibernate的一级和二级缓存

    一级缓存就是Session级别的缓存,close后就没了. 二级缓存就是SessionFactory级别的缓存,全局缓存,要配置其他插件. 什么样的数据适合存放到第二级缓存中? 1.很少被修改的数据 ...

  5. hibernate框架学习之二级缓存(测试用例)

    HqlDemoApp.java package cn.itcast.h3.query.hql; import java.io.Serializable; import org.hibernate.Qu ...

  6. Hibernate 集成 Ehcache 开启二级缓存

    一.将 Ehcache.xml 放到 classpath 下 <?xml version="1.0" encoding="UTF-8"?> < ...

  7. hibernate学习 六 Hibernate缓存

    缓存: 如果在集群环境下使用Hibernate时,(集群有节点A ,节点B) 当请求,发往A节点,A在数据库中修改了一条记录,然后节点B的缓存中如何实时的更新节点A修改的新数据          hi ...

  8. 【Hibernate】Hibernate系列7之二级缓存

    二级缓存 7.1.概述 7.2.配置方法

  9. Hibernate 性能优化之二级缓存

    二级缓存是一个共享缓存,在二级缓存中存放的数据是共享数据特性     修改不能特别频繁     数据可以公开二级缓存在sessionFactory中,因为sessionFactory本身是线程安全,所 ...

  10. Hibernate第十二篇【二级缓存介绍、缓存策略、查询缓存、集合缓存】

    Hibernate二级缓存介绍 前面我们已经讲解过了一级缓存,一级缓存也就是Session缓存,只在Session的范围内有效-作用时间就在Session的作用域中,范围比较小 Hibernate为我 ...

随机推荐

  1. python统计词频

    arr = [1,2,3,4,5,6,4,5,2,3,6,8,9,6,5,3,6,2,4]dic={}for item in arr: if item in dic.keys(): dic[item] ...

  2. [译文] SQL JOIN,你想知道的应该都有

    介绍 这是一篇阐述SQL JOINs的文章. 背景 我是个不喜欢抽象的人,一图胜千言.我在网上查找了所有的关于SQL JOIN的解释,但是没有找到一篇能用图像形象描述的. 有些是有图片的但是他们没有覆 ...

  3. http,socks4,socks5代理的区别

    HTTP代理 能够代理客户机的HTTP访问,主要是代理浏览器访问网页,它的端口一般为80.8080.3128等: SOCKS代理 SOCKS代理与其他类型的代理不同,它只是简单地传递数据包,而并不关心 ...

  4. 数据库 --> SQL 和 NoSQL 的区别

    SQL 和 NoSQL 的区别   一.概念 SQL (Structured Query Language) 数据库,指关系型数据库.主要代表:SQL Server,Oracle,MySQL(开源), ...

  5. Nginx配置文件nginx.conf中文详解(转)

    #定义Nginx运行的用户和用户组user www www; #nginx进程数,建议设置为等于CPU总核心数.worker_processes 8; #全局错误日志定义类型,[ debug | in ...

  6. java开发常用技术

    基础部分 1. 线程和进程的区别 线程三个基本状态:就绪.执行.阻塞 线程五个基本操作:创建.就绪.运行.阻塞.终止 进程四种形式:主从式.会话式.消息或邮箱机制.共享存储区方式 进程是具有一定功能的 ...

  7. Android中文API (110) —— CursorTreeAdapter

    前言 本章内容是android.widget.CursorTreeAdapter,版本为Android 3.0 r1,翻译来自"深夜未眠",欢迎访问它的博客:"http: ...

  8. hihocoder [Offer收割]编程练习赛52 D 部门聚会

    看了题目的讨论才会做的 首先一点,算每条边(u, v)对于n*(n+1)/2种[l, r]组合的贡献 正着算不如反着算 哪些[l, r]的组合没有包含这条边(u, v)呢 这个很好算 只需要统计u这半 ...

  9. bootstrap 模态框(modal)插件使用

    今天用户登陆时,在原网页上弹出新登陆窗口,发现使用的是modal插件,记录下该插件的使用方法,手写强化下. 首先,模态框(modal)是覆盖在父窗体上的子窗体,目的是显示来自一个单独的源的内容,可以在 ...

  10. alpha-咸鱼冲刺day1-紫仪

    总汇链接 一,合照 emmmmm.自然是没有的. 二,项目燃尽图 三,项目进展   登陆界面随意写了一下.(明天用来做测试的) 把学姐给我的模板改成了自家的个人主页界面,侧边栏啥的都弄出来了(快撒花花 ...