话说:Hibernate二级缓存
Hibernate缓存分类:
一、Session缓存(又称作事务缓存):Hibernate内置的,不能卸除。
缓存范围:缓存只能被当前Session对象访问。缓存的生命周期依赖于Session的生命周期,当Session被关闭后,缓存也就结束生命周期。
二、SessionFactory缓存(又称作应用缓存):使用第三方插件,可插拔。
缓存范围:缓存被应用范围内的所有session共享,不同的Session可以共享。这些session有可能是并发访问缓存,因此必须对缓存进行更新。缓存的生命周期依赖于应用的生命周期,应用结束时,缓存也就结束了生命周期,二级缓存存在于应用程序范围。
缓存:但是一般人的理解在内存中的一块空间,可以将二级缓存配置到硬盘。用白话来说,就是一个存储数据的容器。我们关注的是,哪些数据需要被放入二级缓存。
缓存:是计算机领域的概念,它介于应用程序和永久性数据存储源之间。
作用:降低应用程序直接读写数据库的频率,从而提高程序的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存。

Hibernate的缓存一般分为3类:
一级缓存
二级缓存
查询缓存

如果希望一个Java对象一直处于声明周期中,就必须保证至少有一个变量引用它,或者在一个Java集合中存放了这个对象的引用。在Session接口的实现咧SessionImpl中定义了一系列的Java集合,这些Java集合构成了Session的缓存。

以下方法支持一级缓存:金牌结论
* get()
* load()
* iterate(查询实体对象)
其中 Query 和Criteria的list() 只会缓存,但不会使用缓存(除非结合查询缓存)。
一级缓存
01.Session内的缓存即一级缓存,内置且不能被卸载,一个事务内有效。
02.Session为应用程序提供了管理缓存的方法:
evict(Object o)
clear()
03.金牌讲解一级缓存
一级缓存的生命周期和session的生命周期一致,当前session一旦关闭,一级缓存就消失了,因此一级缓存也叫session级的缓存或事务级缓存,一级缓存只存实体对象,它不会缓存一般的对象属性(查询缓存可以),即当获得对象后,就将该对象缓存起来,如果在同一session中再去获取这个对象时,它会先判断在缓存中有没有该对象的id,如果有则直接从缓存中获取此对象,反之才去数据库中取,取的同时再将此对象作为一级缓存处理。
二级缓存
开发中的用于没有面试带来作用大。
二级缓存是进程或集群范围内的缓存,可以被所有的Session共享
二级缓存是可配置的插件

二级缓存的配置使用(ehcache缓存)
*.引入如下jar包。
ehcache-1.2..jar 核心库
backport-util-concurrent.jar
commons-logging.jar
*.配置Hibernate.cfg.xml开启二级缓存
<property name="hibernate.cache.use_second_level_cache">true</property>
*.配置二级缓存的供应商
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
*.指定使用二级缓存的类
方案一:在*.hbm.xml中配置
在<class元素的子元素下添加chche子节点,但该配置仅会缓存对象的简单属性,若希望缓存集合属性中的元素,必须在set元素中添加<cache>子元素
<class name="Student" table="STUDENT">
<cache usage="read-write"/>
在大配置文件(hibernate.cfg.xml)中配置
<class-cache usage="read-write" class="cn.happy.entity.Student"/>
<collection-cache usage="read-write" collection=""/>
*5.在src下添加ehcache.xml文件,从etc获取文件即可。
测试: 二级缓存 数据散装 的特点
Session session = HibernateUtil.getSession();
Transaction tx=session.beginTransaction();
Dept dept = (Dept)session.get(Dept.class,);
System.out.println(dept); Dept dept2 = (Dept)session.get(Dept.class,);
System.out.println(dept2);
tx.commit(); Session session2 = HibernateUtil.getSession();
Transaction tx2=session2.beginTransaction();
Dept dept3 = (Dept)session2.get(Dept.class,);
System.out.println(dept3);
tx2.commit();

解析:每次从二级缓存中取出的对象,都是一个新的对象。、
测试: 使用list 将数据存储到二级缓存中(只能往二级缓存中存数据 不能取出数据) 在从二级缓存中取出数据时 会重新从数据库取数据(重新生成sql)
List<Carport> list = session.createQuery("from Carport").list();
System.out.println(list.get().getLocation());
HibernateUtil.closeSession();
System.out.println("==========");
Session session2 = (Session) HibernateUtil.getSession();
List<Carport> list2 = session2.createQuery("from Carport").list();
System.out.println(list.get().getLocation());

解析: 可以看到 我们上面的list()操作仅仅是将数据存储到了缓存中 却不能从内存中取出数据(生成了第二道sql查询语句)。
测试:iterator()方法可以读取二级缓存中的数据
首先说明:
iterator()会先到数据库中把id都取出来,然后真正要遍历某个对象的时候先到缓存中找,如果找不到,以id为条件再发一条sql到数据库,
这样如果缓存中没有数据,则查询数据库的次数为n+1。 iterate中返回的对象是代理对象
Query query = session.createQuery("from Carport");
Iterator iterate = query.iterate();
while (iterate.hasNext()) {
System.out.println(((Carport)iterate.next()).getLocation());
}
HibernateUtil.closeSession();
System.out.println("==========");
Session session2 = (Session) HibernateUtil.getSession();
Query query2 = session2.createQuery("from Carport");
Iterator iterate2 = query2.iterate();
while (iterate2.hasNext()) {
System.out.println(((Carport)iterate2.next()).getLocation());
}

解析:要遍历某个对象的时候先到缓存中找,如果找不到,以id为条件再发一条sql到数据库。(iterator()可以从缓存中取出数据来)
测试: 集合级别缓冲区
二级缓存的策略
当多个并发的事务同时访问持久化层的缓存中的相同数据时,会引起并发问题,必须采用必要的事务隔离措施。
在进程范围或集群范围的缓存,即第二级缓存,会出现并发问题。因此可以设定以下4种类型的并发访问策略,每一种策略对应一种事务隔离级别。
● 只读缓存(read-only)
如果应用程序需要读取一个持久化类的实例,但是并不打算修改它们,可以使用read-only缓存。这是最简单,也是实用性最好的策略。
对于从来不会修改的数据,如参考数据,可以使用这种并发访问策略。
● 读/写缓存(read-write)
如果应用程序需要更新数据,可能read-write缓存比较合适。如果需要序列化事务隔离级别,那么就不能使用这种缓存策略。
对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读这类的并发问题。
● 不严格的读/写缓存(nonstrict-read-write)
如果程序偶尔需要更新数据(也就是说,出现两个事务同时更新同一个条目的现象很不常见),也不需要十分严格的事务隔离,可能适用nonstrict-read-write缓存。
对于极少被修改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。
● 事务缓存(transactional)
transactional缓存策略提供了对全事务的缓存,仅仅在受管理环境中使用。它提供了Repeatable Read事务隔离级别。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读和不可重复读这类的并发问题。
在上面所介绍的隔离级别中,事务型并发访问策略的隔离级别最高,然后依次是读/写型和不严格读写型,只读型的隔离级别最低。事务的隔离级别越高,并发性能就越低。

查询缓存
1,查询是数据库技术中最常用的操作,Hibernate为查询提供了缓存,用来提高查询速度,优化查询性能
相同HQL语句检索结果的缓存!
2,查询缓存依赖于二级缓存
查询缓存是针对普通属性结果集的缓存,对实体对象的结果集只缓存id(其id不是对象的真正id,可以看成是HQL或者SQL语句,它与查询的条件相关即where后的条件相关,不同的查询条件,其缓存的id也不一样)。查询缓存的生命周期,当前关联的表发生修改或是查询条件改变时,那么查询缓存生命周期结束,它不受一级缓存和二级缓存生命周期的影响,要想使用查询缓存需要手动配置如下:
* 在hibernate.cfg.xml文件中启用查询缓存,如:
<property name="hibernate.cache.use_query_cache">true</property>
* 在程序中必须手动启用查询缓存,如:
query.setCacheable(true);
其中 Query 和Criteria的list() 就可利用到查询缓存了。

注意:
不要想当然的以为缓存可以提高性能,仅仅在你能够驾驭它并且条件合适的情况下才是这样的。hibernate的二级缓存限制还是比较多的。在不了解原理的情况下乱用,可能会有1+N的问题。不当的使用还可能导致读出脏数据。 如果受不了hibernate的诸多限制,那么还是自己在应用程序的层面上做缓存吧。
在越高的层面上做缓存,效果就会越好。就好像尽管磁盘有缓存,数据库还是要实现自己的缓存,尽管数据库有缓存,咱们的应用程序还是要做缓存。因为底层的缓存它并不知道高层要用这些数据干什么,只能做的比较通用,而高层可以有针对性的实现缓存,所以在更高的级别上做缓存,效果也要好些吧。
缓存是位于应用程序与物理数据源之间,用于临时存放复制数据的内存区域,目的是为了减少应用程序对物理数据源访问的次数,从而提高应用程序的运行性能.
Hibernate在查询数据时,首先到缓存中去查找,如果找到就直接使用,找不到的时候就会从物理数据源中检索,所以,把频繁使用的数据加载到缓存区后,就可以大大减少应用程序对物理数据源的访问,使得程序的运行性能明显的提升.
后续更新。。。
话说:Hibernate二级缓存的更多相关文章
- Hibernate ——二级缓存
一.Hibernate 二级缓存 1.Hibernate 二级缓存是 SessionFactory 级别的缓存. 2.二级缓存分为两类: (1)Hibernate内置二级缓存 (2)外置缓存,可配置的 ...
- 配置Hibernate二级缓存时,不能初始化RegionFactory的解决办法
配置Hibernate 二级缓存时,出现以下bug提示: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder&quo ...
- 配置Hibernate二级缓存步骤
配置Hibernate二级缓存步骤: 加入二级缓存的jar包及配置文件 jar包位置:hibernate-release-4.1.8.Final\lib\optional\ehcache下所有jar包 ...
- Hibernate 二级缓存 总结整理(转)
和<Hibernate 关系映射 收集.总结整理> 一样,本篇文章也是我很早之前收集.总结整理的,在此也发上来 希望对大家有用.因为是很早之前写的,不当之处请指正. 1.缓存:缓存是什么, ...
- Hibernate(十六):Hibernate二级缓存
Hibernate缓存 缓存(Cache):计算机领域非常通用的概念.它介于应用程序和永久性数据存储源(如磁盘上的文件或者数据库)之间,起作用是降低应用程序直接读取永久性数据存储源的频率,从而提高应用 ...
- hibernate二级缓存demo2
@Test public void hello3(){ Session session=sessionFactory.openSession(); List list = session.create ...
- hibernate二级缓存整合
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http:// ...
- ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存
ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存 hibernate : Hibernate是一个持久层框架,经常访问物理数据库 ...
- spring boot集成ehcache 2.x 用于hibernate二级缓存
https://www.jianshu.com/p/87b2c309b776 本文将介绍如何在spring boot中集成ehcache作为hibernate的二级缓存.各个框架版本如下 spring ...
- js相关(easyUI),触发器,ant,jbpm,hibernate二级缓存ehcache,Javamail,Lucene,jqplot,WebService,regex,struts2,oracle表空间
*********************************************js相关********************************************* // 在指 ...
随机推荐
- 二、第一个ECharts图表
<!DOCTYPE html> <head> <meta charset="utf-8"> <title>ECharts</t ...
- Codeforces Round #226 (Div. 2) C题
数论好题 题目要求:求给定序列的素因子如果在给定区间内该数字个数加1; 思路:打表时求出包含给素数因子的数的个数,详见代码 1 #include<cstring> +; scan ...
- noip模拟赛 蒜头君救人
分析:之前的一道模拟赛题是dp+dfs,这道题是dp+bfs. 我们设f[stu][i][j]为当前状态为stu,走到(i,j)的答案,考虑怎么设计stu,每个人的状态有3种:要么在原地,要么被背着, ...
- js 发布订阅模式
//发布订阅模式 class EventEmiter{ constructor(){ //维护一个对象 this._events={ } } on(eventName,callback){ if( t ...
- Drools介绍与使用
Drools 是用 Java 语言编写的开放源码规则引擎,使用 Rete 算法对所编写的规则求值.Drools 允许使用声明方式表达业务逻辑.可以使用非 XML 的本地语言编写规则,从而便于学习和理解 ...
- [bzoj1001]狼爪兔子[平面图的最小割等于其对偶图的最短路]
一定要仔细算内存,,,又少写一个零.. #include <bits/stdc++.h> using namespace std; template<const int _n,con ...
- NetCore发布WebApi项目到IIS服务器中
1.确保已在机器上安装Net Core Runtime,,下载地址: https://dotnet.microsoft.com/download 2.点击WebApi项目右键->发布,选择IIS ...
- HDU 1133 Buy the Ticket 卡特兰数
设50元的人为+1 100元的人为-1 满足前随意k个人的和大于等于0 卡特兰数 C(n+m, m)-C(n+m, m+1)*n!*m! import java.math.*; import java ...
- javascript中数组的定义及使用
js <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.o ...
- linux查找nginx所在目录
ps -ef |grep nginx