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 】
相关推荐:
在线教育网站制作平台,山西立德教育官网?
如何快速重置建站主机并恢复默认配置?
详解vue.js组件化开发实践
如何在 React 中条件性地遍历数组并渲染元素
如何在新浪SAE免费搭建个人博客?
香港服务器网站推广:SEO优化与外贸独立站搭建策略
Win11怎样安装网易有道词典_Win11安装词典教程【步骤】
北京的网站制作公司有哪些,哪个视频网站最好?
佛山企业网站制作公司有哪些,沟通100网上服务官网?
Laravel怎么导出Excel文件_Laravel Excel插件使用教程
Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】
Python制作简易注册登录系统
Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置
如何用搬瓦工VPS快速搭建个人网站?
黑客如何利用漏洞与弱口令入侵网站服务器?
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
如何快速搭建二级域名独立网站?
Laravel如何使用Eloquent ORM进行数据库操作?(CRUD示例)
如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南
如何快速登录WAP自助建站平台?
深圳网站制作的公司有哪些,dido官方网站?
Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权
Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】
Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全
中山网站制作网页,中山新生登记系统登记流程?
ChatGPT 4.0官网入口地址 ChatGPT在线体验官网
Laravel怎么写单元测试_PHPUnit在Laravel项目中的基础测试入门
Laravel API资源(Resource)怎么用_格式化Laravel API响应的最佳实践
如何在建站之星网店版论坛获取技术支持?
微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】
JavaScript如何实现错误处理_try...catch如何捕获异常?
Claude怎样写结构化提示词_Claude结构化提示词写法【教程】
Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
谷歌Google入口永久地址_Google搜索引擎官网首页永久入口
Linux系统命令中screen命令详解
如何在建站宝盒中设置产品搜索功能?
Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】
Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧
如何在宝塔面板中修改默认建站目录?
Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比
高端智能建站公司优选:品牌定制与SEO优化一站式服务
网站制作大概多少钱一个,做一个平台网站大概多少钱?
香港服务器选型指南:免备案配置与高效建站方案解析
如何基于PHP生成高效IDC网络公司建站源码?
如何用西部建站助手快速创建专业网站?
如何用花生壳三步快速搭建专属网站?
原生JS实现图片轮播切换效果
Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】
如何快速搭建虚拟主机网站?新手必看指南

