hibernate缓存详解
hibernate中提供了两级缓存,一级缓存是Session级别的缓存,它属于事务范围的缓存,该级缓存由hibernate管理,应用程序无需干预;二级缓存是SessionFactory级别的缓存,该级缓存可以进行配置和更改,并且可以动态加载和卸载,hibernate还为查询结果提供了一个查询缓存,它依赖于二级缓存;
一、什么是缓存
缓存是位于应用程序和永久性数据存储源之间用于临时存放复制数据的内存区域,缓存可以降低应用程序之间读写永久性数据存储源的次数,从而提高应用程序的运行性能;
hibernate在查询数据时,首先会到缓存中查找,如果找到就直接使用,找不到时才从永久性数据存储源中检索,因此,把频繁使用的数据加载到缓存中,可以减少应用程序对永久性数据存储源的访问,使应用程序的运行性能得以提升。
换言之,就是用空间换时间。
二、缓存优劣势
优势:提升性能,节约时间。
劣势:占内存。不及时性。
三、缓存何时使用
1.内存小
2.更新快
3.访问频率低
4.缓存版本多
四、缓存分类
一级缓存 - 默认带的。Session内的缓存。Session 提交之前。访问可以自动读缓存。
@Test
public void testfirstleve1(){
Session session = null;
try{
session = HibernateUtil.getSession();
Info data1 = session.get(Info.class, "p003");
HibernateUtil.closeSession();
session = HibernateUtil.getSession();//删除这一行以及上面一行时,返回的结果为true
Info data2 = session.get(Info.class, "p003");
System.out.println(data1==data2);
}
catch(Exception e){
e.printStackTrace();
}
finally{
HibernateUtil.closeSession();
}
}
使用 load和get加载对象的时候,会自动加载到缓存,读取的也会读缓存。
使用hql查询多条数据库,如果使用getResultList()默认是无法放到缓存中的。使用iterator()可以用在缓存中。
@Test
public void testfirstleve2(){
Session session = null;
try{
session = HibernateUtil.getSession();
//
// Iterator<Info> iter= session.createQuery("from Info").iterate();
// while(iter.hasNext()){
// System.out.println(iter.next().getName());
// }
// Iterator<Info> iter1= session.createQuery("from Info").iterate();
// while(iter1.hasNext()){
// System.out.println(iter1.next().getName());
// } List<Info> list1 = session.createQuery("from Info").getResultList();
List<Info> list2 = session.createQuery("from Info").getResultList();
System.out.println(list1==list2);
}
catch(Exception e){
e.printStackTrace();
}
finally{
HibernateUtil.closeSession();
}
}
输出如下:
Hibernate: select info0_.Code as Code1_1_, info0_.Nation as Nation2_1_, info0_.Name as Name3_1_, info0_.Sex as Sex4_1_, info0_.Birthday as Birthday5_1_ from mydb.info info0_
Hibernate: select info0_.Code as Code1_1_, info0_.Nation as Nation2_1_, info0_.Name as Name3_1_, info0_.Sex as Sex4_1_, info0_.Birthday as Birthday5_1_ from mydb.info info0_
false
若是把上面注释的解开:
Hibernate: select info0_.Code as col_0_0_ from mydb.info info0_
Hibernate: select info0_.Code as Code1_1_0_, info0_.Nation as Nation2_1_0_, info0_.Name as Name3_1_0_, info0_.Sex as Sex4_1_0_, info0_.Birthday as Birthday5_1_0_ from mydb.info info0_ where info0_.Code=?
周丹
Hibernate: select info0_.Code as Code1_1_0_, info0_.Nation as Nation2_1_0_, info0_.Name as Name3_1_0_, info0_.Sex as Sex4_1_0_, info0_.Birthday as Birthday5_1_0_ from mydb.info info0_ where info0_.Code=?
唐墨
Hibernate: select info0_.Code as Code1_1_0_, info0_.Nation as Nation2_1_0_, info0_.Name as Name3_1_0_, info0_.Sex as Sex4_1_0_, info0_.Birthday as Birthday5_1_0_ from mydb.info info0_ where info0_.Code=?
胡
Hibernate: select info0_.Code as Code1_1_0_, info0_.Nation as Nation2_1_0_, info0_.Name as Name3_1_0_, info0_.Sex as Sex4_1_0_, info0_.Birthday as Birthday5_1_0_ from mydb.info info0_ where info0_.Code=?
吴倩
Hibernate: select info0_.Code as col_0_0_ from mydb.info info0_
周丹
唐墨
胡
吴倩
可以看到用iterator()的时候,第一遍是查询语句,第二遍是读取的缓存。
二级缓存 - 需要扩展外部插件。SessionFactory内的缓存。Session关了后,只要SessionFactory没有close,还可以使用缓存。
配置EhCache二级缓存:
1.复制三个包到lib文件夹下;
2.在hibernate.cfg.xml中配置,启动二级缓存
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
3.把ehcache配置文件复制过来
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
-->
<ehcache> <!-- Sets the path to the directory where cache .data files are created. If the path is a Java System Property it is replaced by
its value in the running VM. The following properties are translated:
user.home - User's home directory
user.dir - User's current working directory
java.io.tmpdir - Default temp file path -->
<diskStore path="java.io.tmpdir"/> <!--Default Cache configuration. These will applied to caches programmatically created through
the CacheManager. The following attributes are required for defaultCache: maxInMemory - Sets the maximum number of objects that will be created in memory
eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element
is never expired.
timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
if the element is not eternal. Idle time is now - last accessed time
timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
if the element is not eternal. TTL is now - creation time
overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit. -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/> <!--Predefined caches. Add your cache configuration settings here.
If you do not have a configuration for your cache a WARNING will be issued when the
CacheManager starts The following attributes are required for defaultCache: name - Sets the name of the cache. This is used to identify the cache. It must be unique.
maxInMemory - Sets the maximum number of objects that will be created in memory
eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element
is never expired.
timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
if the element is not eternal. Idle time is now - last accessed time
timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
if the element is not eternal. TTL is now - creation time
overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit. --> <!-- Sample cache named sampleCache1
This cache contains a maximum in memory of 10000 elements, and will expire
an element if it is idle for more than 5 minutes and lives for more than
10 minutes. If there are more than 10000 elements it will overflow to the
disk cache, which in this configuration will go to wherever java.io.tmp is
defined on your system. On a standard Linux system this will be /tmp"
-->
<cache name="sampleCache1"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="true"
/> <!-- Sample cache named sampleCache2
This cache contains 1000 elements. Elements will always be held in memory.
They are not expired. -->
<cache name="sampleCache2"
maxElementsInMemory="1000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
/> --> <!-- Place configuration for your caches following --> </ehcache>
4.在实体对象的映射文件中的<class>下配置缓存。
<cache usage="read-write"/>这句话放在<class>下的第一句
5.如果使用load或get的时候,不需要其它操作,直接使用的二缓存,中间session关闭也没关系
查询缓存--根据HQL不同,缓存不同的结果
在二级缓存的基础上。加两块:
1.hibernate.cfg.xml中加上
<property name="hibernate.cache.use_query_cache">true</property> <!-- 缓存查询语句,相同的查询语句就不再去查第二遍,但对象没有缓存 -->
2.在HQL的createQuery()后加上setCacheable(true)。
@Test
public void testsecondleve(){
Session session = null;
try{
session = HibernateUtil.getSession(); List<Info> list1 = session.createQuery("from Info").setCacheable(true).getResultList();
List<Info> list2 = session.createQuery("from Info").setCacheable(true).getResultList();
System.out.println(list1==list2);
}
catch(Exception e){
e.printStackTrace();
}
finally{
HibernateUtil.closeSession();
}
}
Hibernate: select info0_.Code as Code1_1_, info0_.Nation as Nation2_1_, info0_.Name as Name3_1_, info0_.Sex as Sex4_1_, info0_.Birthday as Birthday5_1_ from mydb.info info0_
false
这里的list1与list2都是查找同样的from info的hql语句,如果1与2的语句稍有不同,那么返回的查询语句就是两条,不是一条了。
对于返回List<T>对象,使用查询缓存。一级,二级缓存是不会缓存集合对象。
hibernate缓存详解的更多相关文章
- JAVA框架之Hibernate【Hibernate缓存详解】
1.缓存介绍 Hibernate中提供了两级Cache,第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存.这一级别的缓存由hibernate管理的,一般情况下无需进行干预:第二级别的缓 ...
- hibernate Expression详解
关键字: hibernate expression hibernate Expression详解Expression.gt:对应SQL条件中的"field > value " ...
- redis使用及配置之缓存详解
redis使用及配置之缓存详解 1.Redis的介绍 Redis是一个Key-Value存储系统.它支持存储的value类型有:string(字符串),list(链表), set(无序集合),zset ...
- 【转】MySQL查询缓存详解
[转]MySQL查询缓存详解 转自:https://www.cnblogs.com/Alight/p/3981999.html 相关文章:http://www.zsythink.net/archive ...
- MySQL查询缓存详解(总结)
MySQL查询缓存详解(总结) 一.总结 一句话总结: mysql查询缓存还是可以用用试一试,但是更推荐分布式,比如redis/memcache之流,将数据库中查询的数据和查询语句以键值对的方式存进分 ...
- [面试专题]Web缓存详解
Web缓存详解 标签(空格分隔): 缓存 缓存之于性能优化 请求更快:通过将内容缓存在本地浏览器或距离最近的缓存服务器(如CDN),在不影响网站交互的前提下可以大大加快网站加载速度. 降低服务器压力: ...
- Hibernate缓存简介和对比、一级缓存、二级缓存详解
一.hibernate缓存简介 缓存的范围分为3类: 1.事务范围(单Session即一级缓存) 事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象 ...
- hibernate二级缓存ehcache hibernate配置详解
<!-----------------hibernate二级缓存ehcache------------------------->hibernate配置 <prop key=&quo ...
- Hibernate配置文件详解
Hibernate配置方式 Hibernate给人的感受是灵活的,要达到同一个目的,我们可以使用几种不同的办法.就拿Hibernate配置来说,常用的有如下三种方式,任选其一. 在 hibernate ...
随机推荐
- UVA 12405 Scarecrow (基础DP)
题意: 给出一个1*N的矩阵(就是一行的格子),其中部分格子可以有草,部分无草,现在要求放置一些稻草人在某些格子上,每个稻草人可以覆盖3个连续格子,为使得有草的格子都能被覆盖,问最少放置几个稻草人. ...
- 到底什么样的ABAP系统能运行Fiori应用
有朋友在微信上问我两个问题: S/4 fiori是标配吗? 如果是ERP R/3,可以激活fiori配置吗? 先回答第二个问题. 在Jerry的微信公众号文章SAP Fiori应用的三种部署方式曾经提 ...
- 重温Javascript(三)-继承
继承 1.原型链继承 基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针.让原型 ...
- UVA 177 PaperFolding 折纸痕 (分形,递归)
著名的折纸问题:给你一张很大的纸,对折以后再对折,再对折……每次对折都是从右往左折,因此在折了很多次以后,原先的大纸会变成一个窄窄的纸条.现在把这个纸条沿着折纸的痕迹打开,每次都只打开“一半”,即把每 ...
- Beta冲刺(周五)
这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1 这个作业要求在哪里 https://edu.cnblo ...
- (原)IPhone开发时把ToolBar中的元素居中的技巧
在IPhone应用开发时,经常用到ToolBar,其中的控件通常都是居左,想让它居中就有点困难. 这里介绍一种方法: 将Flexible Space Bar Button Item从库中拖到位于控件左 ...
- python基础一 day15 作业
3.处理文件,用户指定要查找的文件和内容,将文件中包含要查找内容的每一行都输出到屏幕def check_file(filename,aim): with open(filename,encoding= ...
- Java获取yml里面的配置
#yml文件配置systemPath: #档案系统地址 dossier: http://127.0.0.1:8088/ //调用说明 配置文件里必须包含节点 否则项目无法启动 @Value(" ...
- 一句话懂什么是JS闭包
无论何时声明新函数并将其赋值给变量,都要存储函数定义和闭包.闭包包含在函数创建时作用域中的所有变量,它类似于背包.函数定义附带一个小背包,它的包中存储了函数定义创建时作用域中的所有变量. 我将永远记住 ...
- classpath、WEB-INF
classpath是指 WEB-INF文件夹下的classes目录(war包),对于springboot项目打包出来的jar包,里面的就是BOOT-INF: 这个demo的源码结构如下: 可见,jav ...