hibernate缓存详解

什么是缓存

缓存cache:计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘的文件或者数据库)之间,其作用是降低应用程序直接读写硬盘(永久性数据存储源)的频率,从而提高应用的运行性能,缓存中的数据是数据存储源中的数据拷贝。缓存的物理介质通常是内存。
缓存:程序《-----(内存)----》硬盘

二级缓存

hibernate的一级缓存也叫session级别缓存,在一次请求中共享数据。
hibernate的二级缓存,sessionFactory级别的缓存,整个应用程序共享一个会话工厂,共享一个二级缓存。
sessionFactory的缓存又分为内置缓存和外置缓存。
内置缓存:使用一个Map,用于存放配置信息,预定义HQL语句等,提供Hibernate框架自己使用,对外只读,不能操作
外置缓存:使用另一个Map,用于存放用户自定义数据,默认不开启外置缓存,hibernate只提供规范(接口),需要第三方实现类,外置缓存也被称为二级缓存

二级缓存的架构
image.png

二级缓存的四大部分分别是:类级别缓存、集合级别缓存、时间戳缓存、查询缓存。

并发访问策略
image.png
应用场景

适用放在二级缓存中的数据,很少被修改,不是很重要的数据,允许出现偶尔的并发问题
不适合存在二级缓存的数据,经常被修改,比如财务数据,绝对不允许出现并发问题,与其他应用数据共享的数据

二级缓存提供商

Hibernate中只定义二级缓存接口,实现需要自己选择提供商。
EHCache:可作为进程(单机)范围内的缓存,存放数据的物理介质,可以是内存或硬盘对Hibernate的查询缓存提供了支持,支持集群。
OpenSymphony:可作为进程范围内的缓存,存放数据的物理介质,可以是内存或硬盘。提供了丰富的缓存数据过期策略。对Hibernate的查询缓存提供了支持。
SwarmCache:可作为集群范围内的缓存,但不支持HIbernate的查询缓存
JBOSSCache:可作为集群范围内的缓存,支持Hibernate的查询缓存


image.png
hibernate缓存实战

首先在hibernate项目中导入ehcache相关的jar包,如下图所示:


image.png
类级别缓存
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_second_level_cache">true</property>

<class-cache class="com.zzx.hibernate.domain.Customer" usage="read-only"/>
<class-cache class="com.zzx.hibernate.domain.Order" usage="read-only"/>

然后把jar包中的ehcache failsafe.xml文件复制到项目中的src目录,然后改名为ehcache.xml

ehcache设置临时文件存放位置(缓存一般内存,一定程度时,写入硬盘)
 <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
            />
ehcache属性详解

maxElementsInMemory:设置基于内存的缓存中可存放的对象,最大数目
eternal:设置对象是否为永久的,true标识永久不过期,此时将忽略
timeToIdleSeconds和timeToLiveSeconds属性,默认值是false
timeToIdleSeconds:设置对象空闲最长时间,以秒为单位,超过这个时间,对象过期。当对象过期时,EHCache会把它的缓存清除。如果这个值为0,表示对象可能无限期的处于空闲状态。
timeToLiveSeconds:设置对象生成最长时间,超过这个时间,对象过期,如果此值为0,标识对象可能无限地存在于缓存中,该属性必须大于或等于timeToIdleSeconds属性值。
overflowToDisk:设置基于存在缓存中的对象的数目达到上限后是否把溢出的对象写在基于硬盘的缓存中。
diskPersistent:当JVM结束时是否持久化对象true或false 默认是false。
diskExpiryThreadIntervalSeconds:指定专门用于清除过期对象的监听线程的轮询时间。
memoryStoreEvictionPolicy:当内存缓存达到最大,有新的element加入的时候。移除缓存中element的策略。默认是LRU(最近最少使用,可选的有LFO(最不常使用)和FIFO(先进先出))
类缓存只存放散装数据,一级缓存存放对象本身


image.png
配置集合缓存
<!--配置集合缓存-->
<collection-cache collection="com.zzx.hibernate.domain.Customer.orders" usage="read-only"></collection-cache>
image.png
查询缓存

查询缓存又称为三级缓存,在默认情况下hibernate没有被使用,需要手动开启,它将HQL语句和查询结果进行绑定,通过HQL相同语句可以缓存内容。默认情况下Query只将查询结果存放在一级和二级缓存,不从一级或二级缓存获取数据。
查询缓存就是让Query可以从二级缓存获取内容。

开启查询缓存
<property name="hibernate.cache.use_query_cache">true</property>

查询缓存案例:

Session session = HibernateUtil.openSession();
Query query = session.createQuery("from Customer");
query.setCacheable(true);
List<Customer> customerList = query.list();
System.out.println(customerList);
session.close();

Session session2 = HibernateUtil.openSession();
Query query2 = session2.createQuery("from Customer");
query2.setCacheable(true);
List<Customer> list = query2.list();
System.out.println(list);
session2.close();

控制台输出结果查询

Hibernate: 
    select
        customer0_.id as id0_,
        customer0_.version as version0_,
        customer0_.name as name0_ 
    from
        t_customer customer0_
[Customer{id=1, name='zhangsan', version=0}, Customer{id=2, name='武松', version=0}, Customer{id=3, name='杜十娘', version=0}, Customer{id=4, name='林冲', version=0}]
[Customer{id=1, name='zhangsan', version=0}, Customer{id=2, name='武松', version=0}, Customer{id=3, name='杜十娘', version=0}, Customer{id=4, name='林冲', version=0}]

从上面的结果我们不难看出,执行两次查询结果操作,实际只调用了一次数据库查询

时间戳查询

任何操作都在时间戳中记录操作时间

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容