Hibernate第十二篇【二级缓存介绍、缓存策略、查询缓存、集合缓存】
Hibernate二级缓存介绍
前面我们已经讲解过了一级缓存,一级缓存也就是Session缓存,只在Session的范围内有效…作用时间就在Session的作用域中,范围比较小
Hibernate为我们提供了二级缓存功能:二级缓存是基于应用程序的缓存,所有的Session都可以使用
- Hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架!如果用户想用二级缓存,只需要在hibernate.cfg.xml中配置即可; 不想用,直接移除,不影响代码。
- 如果用户觉得hibernate提供的框架框架不好用,自己可以换其他的缓存框架或自己实现缓存框架都可以。
Hibernate二级缓存:存储的是常用的类
配置二级缓存
既然二级缓存是Hibernate自带的,那么我们可以在hibernate.properties文件中找到对应的信息..
- #hibernate.cache.use_second_level_cache false【二级缓存默认不开启,需要手动开启】
- #hibernate.cache.use_query_cache true 【开启查询缓存】
- ## choose a cache implementation 【二级缓存框架的实现】
- #hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider
- #hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider
- hibernate.cache.provider_class org.hibernate.cache.HashtableCacheProvider 默认实现
- #hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider
- #hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider
- #hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider
通过配置文件我们可以发现,二级缓存默认是不开启的,需要我们手动开启,以下步骤:
- 1)开启二级缓存
- 2)指定缓存框架
- 3)指定哪些类加入二级缓存
开启二级缓存
在hibernate.cfg.xml文件中开启二级缓存
<!-- a. 开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
指定缓存框架
指定Hibernate自带的二级缓存框架就好了
<!-- b. 指定使用哪一个缓存框架(默认提供的) -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
指定哪些类加入二级缓存
<!-- c. 指定哪一些类,需要加入二级缓存 -->
<class-cache usage="read-write" class="zhongfucheng.aa.Monkey"/>
<class-cache usage="read-only" class="zhongfucheng.aa.Cat"/>
测试
我们知道一级缓存是Session的缓存,那么我们在测试二级缓存的时候使用两个Session来测试就好了。如果第二个Session拿到的是缓存数据,那么就证明二级缓存是有用的。
package zhongfucheng.aa;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
public class App5 {
public static void main(String[] args) {
//获取加载配置管理类
Configuration configuration = new Configuration();
//加载类对应的映射文件!
configuration.configure().addClass(Animal.class);
//创建Session工厂对象
SessionFactory factory = configuration.buildSessionFactory();
//得到Session对象
Session session1 = factory.openSession();
//使用Hibernate操作数据库,都要开启事务,得到事务对象
Transaction transaction = session1.getTransaction();
//开启事务
transaction.begin();
Monkey monkey = (Monkey) session1.get(Monkey.class,"40283f815be67f42015be67f43240001" );
System.out.println(monkey.getName());
System.out.println("-----------------------");
Session session2 = factory.openSession();
Transaction transaction2 = session2.getTransaction();
transaction2.begin();
Monkey monkey2 = (Monkey) session1.get(Monkey.class, "40283f815be67f42015be67f43240001");
System.out.println(monkey2.getName());
//提交事务
transaction.commit();
transaction2.commit();
//关闭Session
session1.close();
session2.close();
}
}
得到的是缓存数据!
缓存策略
我们在把Animal类放进二级缓存的时候,用法为只读
也就是说,只能读取,不能写入,我们来看看写入会怎么样:
monkey2.setName("小猴子");
抛出了异常….
usage的属性有4种:
- 放入二级缓存的对象,只读;
- 非严格的读写
- 读写; 放入二级缓存的对象可以读、写;
- (基于事务的策略)
集合缓存
如果我们在数据库查询的数据是集合…Hibernate默认是没有为集合数据设置二级缓存的…因此还是需要去读写数据库的信息
接下来,我们就看看把集合设置为二级缓存是什么做的:
- 在hibernate.cgf.xml中配置对象中的集合为二级缓存
<!-- 集合缓存[集合缓存的元素对象,也加加入二级缓存] -->
<collection-cache usage="read-write" collection="cn.itcast.b_second_cache.Dept.emps"/>
- 测试代码:
public void testCache() {
Session session1 = sf.openSession();
session1.beginTransaction();
// a. 查询一次
Dept dept = (Dept) session1.get(Dept.class, 10);
dept.getEmps().size();// 集合
session1.getTransaction().commit();
session1.close();
System.out.println("------");
// 第二个session
Session session2 = sf.openSession();
session2.beginTransaction();
// a. 查询一次
dept = (Dept) session2.get(Dept.class, 10); // 二级缓存配置好; 这里不查询数据库
dept.getEmps().size();
session2.getTransaction().commit();
session2.close();
}
查询缓存
list()和iterator()会把数据放在一级缓存,但一级缓存只在Session的作用域中有效…如果想要跨Session来使用,就要设置查询缓存
我们在配置文件中还看到了查询缓存这么一条配置..
#hibernate.cache.use_query_cache true 【开启查询缓存】
也就是说,默认的查询数据是不放在二级缓存中的,如果我们想要把查询出来的数据放到二级缓存,就需要在配置文件中开启
<!-- 开启查询缓存 -->
<property name="hibernate.cache.use_query_cache">true</property>
- 在使用程序查询的时候,也要调用setCacheable()方法,设置为查询缓存。
@Test
public void listCache() {
Session session1 = sf.openSession();
session1.beginTransaction();
// HQL查询 【setCacheable 指定从二级缓存找,或者是放入二级缓存】
Query q = session1.createQuery("from Dept").setCacheable(true);
System.out.println(q.list());
session1.getTransaction().commit();
session1.close();
Session session2 = sf.openSession();
session2.beginTransaction();
q = session2.createQuery("from Dept").setCacheable(true);
System.out.println(q.list()); // 不查询数据库: 需要开启查询缓存
session2.getTransaction().commit();
session2.close();
}
Hibernate第十二篇【二级缓存介绍、缓存策略、查询缓存、集合缓存】的更多相关文章
- Python开发【第二十二篇】:Web框架之Django【进阶】
Python开发[第二十二篇]:Web框架之Django[进阶] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...
- 解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译)
解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译) http://improve.dk/orcamdf-row-compression-support/ 在这两个月的断断续续的开发 ...
- 第十二篇 SQL Server代理多服务器管理
本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...
- 第十二篇 Integration Services:高级日志记录
本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...
- 【译】第十二篇 Integration Services:高级日志记录
本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...
- 【译】第十二篇 SQL Server代理多服务器管理
本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...
- 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探
SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...
- Spring Cloud第十二篇 | 消息总线Bus
本文是Spring Cloud专栏的第十二篇文章,了解前十一篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring ...
- Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇)
Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 目录 Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 1 Internal Locking Methods Row-Leve ...
随机推荐
- Azkaban3.x集群部署(multiple executor mode)
介绍 Azkaban是由Linkedin公司推出的一个批量工作流任务调度器,用于在一个工作流内以一个特定的顺序运行一组工作和流程.Azkaban使用job配置文件建立任务之间的依赖关系,并提供一个易于 ...
- javascript DOM 笔记
以下内容来自<javasript DOM 编程艺术>第二版 dom中三种重要的节点:元素节点.属性节点.文本节点. 几种节点的重要属性:nodeValue,nodeType(为数字1.2. ...
- Andrew Ng机器学习课程笔记--week3(逻辑回归&正则化参数)
Logistic Regression 一.内容概要 Classification and Representation Classification Hypothesis Representatio ...
- ubuntu安装新版QQ
我一直无法解决Ubuntu QQ问题,而最近我重装ubuntu之后在网络上找到与QQ相关的内容,网上有大神开发出了新版的wineQQ,解决了我们对QQ的需求.经过尝试,完成了QQ安装 如图 安装的是w ...
- Python3使用Print输出带颜色字体
Phton3使用print输出带颜色的彩色字体 实现过程: 终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. 转义序列是以ESC开头,即用\03 ...
- NTP原理及配置使用
一.NTP简介 1.NTP简介 NTP(Network Time Protocol,网络时间协议)是用来使网络中的各个计算机时间同步的一种协议.它的用途是把计算机的时钟同步到世界协调时UTC,其精 ...
- SoapUI进行接口测试,怎么应对接口地址总是变化!
如果是没有代码能力的小白,要利用工具进行接口测试的时候,经常会遇到接口地址或者接口参数变化的问题,然后不得不在他们改了接口之后,就手动去改所有的请求链接地址和接口参数!1-5个请求,我们手动改还应付的 ...
- 堆排序—Java
堆排序: 一棵完全二叉树,如果父节点的值大于等于左右节点的值,则称此完全二叉树为小根堆(小顶堆):如果父节点的值小于等于左右节点的值,则次完全二叉树为大根堆(大顶堆). 堆排序是建立在大顶堆或小顶堆的 ...
- web安全普及:通俗易懂,如何让网站变得更安全?以实例来讲述网站入侵原理及防护。
本篇以我自己的网站[http://www.1996v.com]为例来通俗易懂的讲述如何防止网站被入侵,如何让网站更安全. 要想足够安全,首先得知道其中的道理. 本文例子通俗易懂,从"破解网站 ...
- clob字段的值插入和查询N种方法【包括java调用存储过程传入clob参数】
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import jav ...