java中hibernate二级缓存详解
发布时间 - 2026-01-11 01:00:29 点击率:次Hibernate的二级缓存

一、缓存概述
缓存(Cache): 计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存
hibernate中提供了两个级别的缓存
第一级别的缓存是 Session 级别的缓存,它是属于事务范围的缓存。这一级别的缓存由 hibernate 管理的,一般情况下无需进行干预
第二级别的缓存是 SessionFactory 级别的缓存,它是属于进程范围的缓存
Hibernate 的缓存可以分为两类:
内置缓存: Hibernate 自带的, 不可卸载. 通常在 Hibernate 的初始化阶段, Hibernate 会把映射元数据和预定义的 SQL 语句放到 SessionFactory 的缓存中, 映射元数据是映射文件中数据的复制, 而预定义 SQL 语句时 Hibernate 根据映射元数据推到出来的. 该内置缓存是只读的.
外置缓存(二级缓存): 一个可配置的缓存插件. 在默认情况下, SessionFactory 不会启用这个缓存插件. 外置缓存中的数据是数据库数据的复制, 外置缓存的物理介质可以是内存或硬盘
二、理解二级缓存的并发访问策略
三、配置进程范围内的二级缓存(配置ehcache缓存)
1 拷贝ehcache-1.5.0.jar到当前工程的lib目录下
依赖 backport-util-concurrent 和 commons-logging
2 开启二级缓存
<property name="hibernate.cache.use_second_level_cache">true</property>
3 要指定缓存的供应商
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider</property>
4 指定使用二级缓存的类
方法一 在使用类的*.hbm.xml配置
选择需要使用二级缓存的持久化类, 设置它的二级缓存的并发访问策略, <class> 元素的 cache 子元素表明 Hibernate 会缓存对象的简单属性, 但不会缓存集合属性, 若希望缓存集合属性中的元素, 必须在 <set> 元素中加入 <cache> 子元素
方法二 在hibernate.cfg.xml文件中配置(建议)
<!-- 指定使用二级缓存的类 放在maping下面 -->
<!-- 配置类级别的二级缓存 -->
<class-cache class="com.sihai.c3p0.Customer" usage="read-write"/>
<class-cache class="com.sihai.c3p0.Order" usage="read-write"/>
<!-- 配置集合级别的二级缓存 -->
<collection-cache collection="com.sihai.c3p0.Customer.orders"
usage="read-write"/>
5 配置ehcache默认的配置文件ehcache.xml(名字固定)(放在类路径下)
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"> <diskStore path="c:/ehcache"/> <defaultCache maxElementsInMemory="5" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> </ehcache>
四、 测试
package com.sihai.hibernate3.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.sihai.hibernate3.demo1.Customer;
import com.sihai.hibernate3.demo1.Order;
import com.sihai.utils.HibernateUtils;
public class HibernateTest6 {
@Test
// 查询缓存的测试
public void demo9(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select c.cname from Customer c");
// 使用查询缓存:
query.setCacheable(true);
query.list();
tx.commit();
session = HibernateUtils.getCurrentSession();
tx = session.beginTransaction();
query = session.createQuery("select c.cname from Customer c");
query.setCacheable(true);
query.list();
tx.commit();
}
@SuppressWarnings("unused")
@Test
// 更新时间戳
public void demo8(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Customer customer = (Customer) session.get(Customer.class, 2);
session.createQuery("update Customer set cname = '奶茶' where cid = 2").executeUpdate();
tx.commit();
session = HibernateUtils.getCurrentSession();
tx = session.beginTransaction();
Customer customer2 = (Customer) session.get(Customer.class, 2);
tx.commit();
}
@SuppressWarnings("all")
@Test
// 将内存中的数据写到硬盘
public void demo7(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
List<Order> list = session.createQuery("from Order").list();
tx.commit();
}
@Test
// 一级缓存的更新会同步到二级缓存:
public void demo6(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Customer customer = (Customer) session.get(Customer.class, 1);
customer.setCname("芙蓉");
tx.commit();
session = HibernateUtils.getCurrentSession();
tx = session.beginTransaction();
Customer customer2 = (Customer) session.get(Customer.class, 1);
tx.commit();
}
@SuppressWarnings("unchecked")
@Test
// iterate()方法可以查询所有信息.
// iterate方法会发送N+1条SQL查询.但是会使用二级缓存的数据
public void demo5(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// N+1条SQL去查询.
Iterator<Customer> iterator = session.createQuery("from Customer").iterate();
while(iterator.hasNext()){
Customer customer = iterator.next();
System.out.println(customer);
}
tx.commit();
session = HibernateUtils.getCurrentSession();
tx = session.beginTransaction();
iterator = session.createQuery("from Customer").iterate();
while(iterator.hasNext()){
Customer customer = iterator.next();
System.out.println(customer);
}
tx.commit();
}
@SuppressWarnings("unchecked")
@Test
// 查询所有.Query接口的list()方法.
// list()方法会向二级缓存中放数据,但是不会使用二级缓存中的数据.
public void demo4(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// 查询所有客户:
// list方法会向二级缓存中放入数据的.
List<Customer> list = session.createQuery("from Customer").list();
for (Customer customer : list) {
System.out.println(customer.getCname());
}
tx.commit();
session = HibernateUtils.getCurrentSession();
tx = session.beginTransaction();
// Customer customer = (Customer) session.get(Customer.class, 1);// 没有发生SQL ,从二级缓存获取的数据.
// list()方法没有使用二级缓存的数据.
list = session.createQuery("from Customer").list();
for (Customer customer : list) {
System.out.println(customer.getCname());
}
tx.commit();
}
@Test
// 二级缓存的集合缓冲区特点:
public void demo3(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Customer customer = (Customer) session.get(Customer.class, 1);
// 查询客户的订单.
System.out.println("订单的数量:"+customer.getOrders().size());
tx.commit();
session = HibernateUtils.getCurrentSession();
tx = session.beginTransaction();
Customer customer2 = (Customer) session.get(Customer.class, 1);
// 查询客户的订单.
System.out.println("订单的数量:"+customer2.getOrders().size());
tx.commit();
}
@SuppressWarnings("unused")
@Test
// 配置二级缓存的情况
public void demo2(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Customer customer1 = (Customer) session.get(Customer.class, 1);// 发送SQL.
Customer customer2 = (Customer) session.get(Customer.class, 1);// 不发送SQL.
System.out.println(customer1 == customer2);
tx.commit();
session = HibernateUtils.getCurrentSession();
tx = session.beginTransaction();
Customer customer3 = (Customer) session.get(Customer.class, 1);// 不发送SQL.
Customer customer4 = (Customer) session.get(Customer.class, 1);// 不发送SQL.
System.out.println(customer3 == customer4);
tx.commit();
}
@SuppressWarnings("unused")
@Test
// 没有配置二级缓存的情况
public void demo1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Customer customer1 = (Customer) session.get(Customer.class, 1);// 发送SQL.
Customer customer2 = (Customer) session.get(Customer.class, 1);// 不发送SQL.
tx.commit();
session = HibernateUtils.getCurrentSession();
tx = session.beginTransaction();
Customer customer3 = (Customer) session.get(Customer.class, 1);// 发送SQL.
tx.commit();
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# hibernate
# 二级缓存
# hibernate的二级缓存
# 详解Java的Hibernate框架中的缓存与二级缓存
# 详解Java的Hibernate框架中的缓存与原生SQL语句的使用
# 详解Java的Hibernate框架中的注解与缓存
# 浅析Java的Hibernate框架中的缓存和延迟加载机制
# java模拟hibernate一级缓存示例分享
# java中Hibernate缓存形式总结
# 外置
# 放在
# 它是
# 会向
# 应用程序
# 这一
# 更新时间
# 写到
# 会把
# 自带
# 两类
# 推到
# 配置文件
# 大家多多
# 可以分为
# 法会
# 情况下
# 目录下
# usage
# Customer
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
,在苏州找工作,上哪个网站比较好?
浅述节点的创建及常见功能的实现
焦点电影公司作品,电影焦点结局是什么?
Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程
Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】
如何用好域名打造高点击率的自主建站?
Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】
Laravel如何配置Horizon来管理队列?(安装和使用)
如何在云主机快速搭建网站站点?
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】
Laravel如何自定义分页视图?(Pagination示例)
如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)
Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用
VIVO手机上del键无效OnKeyListener不响应的原因及解决方法
如何将凡科建站内容保存为本地文件?
网站制作报价单模板图片,小松挖机官方网站报价?
Claude怎样写结构化提示词_Claude结构化提示词写法【教程】
微信h5制作网站有哪些,免费微信H5页面制作工具?
黑客入侵网站服务器的常见手法有哪些?
Laravel如何从数据库删除数据_Laravel destroy和delete方法区别
微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践
Laravel如何实现多对多模型关联?(Eloquent教程)
Android Socket接口实现即时通讯实例代码
Laravel如何实现全文搜索功能?(Scout和Algolia示例)
javascript和jQuery中的AJAX技术详解【包含AJAX各种跨域技术】
如何获取上海专业网站定制建站电话?
Laravel如何生成和使用数据填充?(Seeder和Factory示例)
QQ浏览器网页版登录入口 个人中心在线进入
Laravel如何使用查询构建器?(Query Builder高级用法)
如何在建站主机中优化服务器配置?
Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用
Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】
Laravel如何自定义错误页面(404, 500)?(代码示例)
如何用PHP快速搭建高效网站?分步指南
Python正则表达式进阶教程_复杂匹配与分组替换解析
Laravel与Inertia.js怎么结合_使用Laravel和Inertia构建现代单页应用
Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】
Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧
JavaScript中的标签模板是什么_它如何扩展字符串功能
手机软键盘弹出时影响布局的解决方法
Laravel事件监听器怎么写_Laravel Event和Listener使用教程
大连网站制作公司哪家好一点,大连买房网站哪个好?
Laravel怎么清理缓存_Laravel optimize clear命令详解
Python文件流缓冲机制_IO性能解析【教程】
Python自动化办公教程_ExcelWordPDF批量处理案例
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
怎么用AI帮你为初创公司进行市场定位分析?

