hibernate笔记--缓存机制之 二级缓存(sessionFactory)和查询缓存

简介: 二级缓存(sessionFactory):   Hibernate的二级缓存由SessionFactory对象管理,是应用级别的缓存。它可以缓存整个应用的持久化对象,所以又称为“SessionFactory缓存”.   hibernate二级缓存中的缓存对象可以被整个应用的Session对象共享,即使关闭当前Session对象,新建的Session对象仍可使用。

二级缓存(sessionFactory):

  Hibernate的二级缓存由SessionFactory对象管理,是应用级别的缓存。它可以缓存整个应用的持久化对象,所以又称为“SessionFactory缓存”.

  hibernate二级缓存中的缓存对象可以被整个应用的Session对象共享,即使关闭当前Session对象,新建的Session对象仍可使用。使用Hibernate的二级缓存之后查询数据,Session对象会首先在以及缓存中查找有无缓存数据被命中。如果没有,则查找二级缓存。如果有,则直接返回所命中的数据;否则查询数据库

  下面介绍在hibernate中如何开启和使用二级缓存:

  1.在hibernate.cfg.xml中开启二级缓存,并且配置cache.region.factory_class:

<!-- 开启二级缓存 -->
    <property name="cache.use_second_level_cache">false</property>
    <!-- 配置cache.region.factory_classs -->
    <property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

  2:导入第三方jar包,(下载hibernate资源包,会在\lib\optional\ehcache文件夹下找到相关jar包):

  3.在src目录下,新建ehcache.xml.或在hibernate资源包的\project\etc目录下找到该文件,copy到src目录下:

    ehcache.xml:

<ehcache>
    <diskStore path="java.io.tmpdir"/>
    <!-- 
        maxElementsInMemory:设置存放对象数量的最大值
        eternal:设置是否永久存储
        timeToIdleSeconds:设置对象的空闲时间
        timeToLiveSeconds:设置对象的存活时间
        overflowToDisk:内存溢出是否写入磁盘
     -->
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />
    <cache name="sampleCache1"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
        />
    <cache name="sampleCache2"
        maxElementsInMemory="1000"
        eternal="true"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
        overflowToDisk="false"
        /></ehcache>

  4:在需要使用二级缓存的实体类的hbm.xml文件中设置,或在hibernate.cfg.xml中指定需要使用二级缓存的实体类:

    以上一节的Book和Category为例,如果我需要开启Book的二级缓存:

      *在Book.hbm.xml文件中的class标签下,添加一个标签:

      <cache usage="read-only"/>

      *或在hibernate.cfg.xml的mapping属性下面,添加:

      <class-cache usage="read-only" class="com.wang.pojo.Book"/>

    关于usage的取值,有以下几种:

只读缓存(read-only):如果应用程序需要读取一个持久化类的实例,但是并不打算修改它们,可以使用read-only缓存。这是最简单,也是实用性最好的策略.

读/写缓存(read-write): 如果应用程序需要更新数据,可能read-write缓存比较合适。如果需要序列化事务隔离级别,那么就不能使用这种缓存策略。

不严格的读/写缓存(nonstrict-read-write):如果程序偶尔需要更新数据(也就是说,出现两个事务同时更新同一个条目的现象很不常见),也不需要十分严格的事务隔离,可能适用nonstrict-read-write缓存。

事务缓存(transactional):  transactional缓存策略提供了对全事务的缓存,仅仅在受管理环境中使用。它提供了Repeatable Read事务隔离级别。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读和不可重复读这类的并发问题。

以上配置工作全部完成,我们来用代码,感受一下二级缓存的存在:

      Session session=HibernateUtil.getSession();
        Book book =(Book) session.get(Book.class,1);
        System.out.println(book.getName());
        session.beginTransaction().commit();
        session.close();
        System.out.println(book.getName());

在这段代码中,我先查询了一下id=1的Book信息,然后关闭了session对象,很明显一级缓存肯定是不存在了,然后我再次打印book的name,我们先看看控制台的打印信息:

神奇的是发生了,居然没有报错,而且打印出了book的name,这就是二级缓存的作用.现在我们再来看看开头的第二段内容,就一目了然了.

hibernate二级缓存中的缓存对象可以被整个应用的Session对象共享,即使关闭当前Session对象,新建的Session对象仍可使用。使用Hibernate的二级缓存之后查询数据,Session对象会首先在以及缓存中查找有无缓存数据被命中。如果没有,则查找二级缓存。如果有,则直接返回所命中的数据;否则查询数据库

 

查询缓存:

  查询缓存缓存的是查询出来的实体的部分属性结果集和实体的ID(注意这里不是实体).关于查询缓存和二级缓存的同时和分开使用的情况,网络上这一段解释的比较好,这里直接引用了:

当只是用Hibernate查询缓存而关闭二级缓存的时候: 
  第一:如果查询的是部分属性结果集: 那么当第二次查询的时候就不会发出SQL,直接从Hibernate查询缓存中取数据;
  第二:如果查询的是实体结果集eg(from Student) ,首先Hibernate查询缓存存放实体的ID,第二次查询的时候就到Hibernate查询缓存中取出ID 一条一条的到数据库查询,这样,将发出N 条SQL造成了SQL泛滥。

当都开启Hibernate查询缓存和二级缓存的时候:
  第一:如果查询的是部分属性结果集: 这个和上面只是用Hibernate查询缓存而关闭 二级缓存的时候一致,因为不涉及实体不会用到二级缓存;
  第二:如果查询的是实体结果集eg(from Student),首先Hibernate查询缓存存放实体的ID,第二次查询的时候,就到Hibernate查询缓存中取出ID,到二级缓存区找数据,如果有数据,就不会发出SQL;如果都有,一条SQL都不会发出,直接从二级缓存中取数据。

下面介绍如何开启和使用查询缓存:

  1.在hibernate.cfg.xml中.添加一个标签语句:

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

  2.在代码中添加query.setCachemodel(true);

    List<Book> list =(List) session.createQuery("from Book")
                              .setCacheable(true)//使用查询缓存
                              .list();
        System.out.println(list.get(0).getName());
        session.beginTransaction().commit();
        session.close();
        System.out.println(list.get(0).getName());

这里使用了list(),查询所有Book信息,关闭session以后再次打印list中的内容,依然能打印出来,不会报错,这就是查询缓存的使用.

注意:

  查询缓存的生命周期与Session无关(可以跨Session查询),当查询关联的表发生改变,那么查询缓存的生命周期结束(delete、update、modify)

  查询缓存是专为Query的list方法设计的。对于iterate()方法,无论是查询对象属性还是对象本身,查询缓存用与不用都没有区别!

相关文章
|
3月前
|
存储 缓存 芯片
让星星⭐月亮告诉你,当我们在说CPU一级缓存二级缓存三级缓存的时候,我们到底在说什么?
本文介绍了CPU缓存的基本概念和作用,以及不同级别的缓存(L1、L2、L3)的特点和工作原理。CPU缓存是CPU内部的存储器,用于存储RAM中的数据和指令副本,以提高数据访问速度,减少CPU与RAM之间的速度差异。L1缓存位于处理器内部,速度最快;L2缓存容量更大,但速度稍慢;L3缓存容量最大,由所有CPU内核共享。文章还对比了DRAM和SRAM两种内存类型,解释了它们在计算机系统中的应用。
128 1
|
4月前
|
缓存 Java 数据库连接
mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)
文章介绍了MyBatis的缓存机制,包括一级缓存和二级缓存的配置和使用,以及如何整合第三方缓存EHCache。详细解释了一级缓存的生命周期、二级缓存的开启条件和配置属性,以及如何通过ehcache.xml配置文件和logback.xml日志配置文件来实现EHCache的整合。
mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)
|
4月前
|
缓存 NoSQL Java
谷粒商城笔记+踩坑(12)——缓存与分布式锁,Redisson+缓存数据一致性
缓存与分布式锁、Redisson分布式锁、缓存数据一致性【必须满足最终一致性】
192 14
谷粒商城笔记+踩坑(12)——缓存与分布式锁,Redisson+缓存数据一致性
|
3月前
|
存储 缓存 索引
从底层数据结构和CPU缓存两方面剖析LinkedList的查询效率为什么比ArrayList低
本文详细对比了ArrayList和LinkedList的查询效率,从底层数据结构和CPU缓存两个方面进行分析。ArrayList基于动态数组,支持随机访问,查询时间复杂度为O(1),且CPU缓存对其友好;而LinkedList基于双向链表,需要逐个节点遍历,查询时间复杂度为O(n),且CPU缓存对其帮助不大。文章还探讨了CPU缓存对数组增删操作的影响,指出缓存主要作用于读取而非修改。通过这些分析,加深了对这两种数据结构的理解。
61 2
|
4月前
|
缓存 NoSQL Java
瑞吉外卖项目笔记+踩坑2——缓存、读写分离优化
缓存菜品、套餐数据、mysql主从复制实现读写分离、前后端分离
瑞吉外卖项目笔记+踩坑2——缓存、读写分离优化
消息中间件 缓存 监控
177 0
|
4月前
|
缓存 NoSQL Java
揭秘性能提升的超级武器:掌握Hibernate二级缓存策略!
【9月更文挑战第3天】在软件开发中,性能优化至关重要。使用Hibernate进行数据持久化的应用可通过二级缓存提升数据访问速度。一级缓存随Session生命周期变化,而二级缓存是SessionFactory级别的全局缓存,能显著减少数据库访问次数,提高性能。要启用二级缓存,需在映射文件或实体类上添加相应配置。然而,并非所有场景都适合使用二级缓存,需根据业务需求和数据变更频率决定。此外,还可与EhCache、Redis等第三方缓存集成,进一步增强缓存效果。合理运用二级缓存策略,有助于大幅提升应用性能。
106 5
|
5月前
|
API Java 数据库连接
从平凡到卓越:Hibernate Criteria API 让你的数据库查询瞬间高大上,彻底告别复杂SQL!
【8月更文挑战第31天】构建复杂查询是数据库应用开发中的常见需求。Hibernate 的 Criteria API 以其强大和灵活的特点,允许开发者以面向对象的方式构建查询逻辑,同时具备 SQL 的表达力。本文将介绍 Criteria API 的基本用法并通过示例展示其实际应用。此 API 通过 API 构建查询条件而非直接编写查询语句,提高了代码的可读性和安全性。无论是简单的条件过滤还是复杂的分页和连接查询,Criteria API 均能胜任,有助于提升开发效率和应用的健壮性。
170 0
|
5月前
|
存储 缓存 NoSQL
微服务复杂查询之缓存策略
微服务复杂查询之缓存策略
|
5月前
|
缓存 关系型数据库 MySQL
【缓存大对决】Memcached VS MySQL查询缓存,谁才是真正的性能之王?
【8月更文挑战第24天】在现代Web应用中,缓存技术对于提升性能与响应速度至关重要。本文对比分析了Memcached与MySQL查询缓存这两种常用方案。Memcached是一款高性能分布式内存对象缓存系统,支持跨服务器共享缓存,具备灵活性与容错性,但受限于内存大小且不支持数据持久化。MySQL查询缓存内置在MySQL服务器中,简化了缓存管理,特别适用于重复查询,但功能较为单一且扩展性有限。两者各有所长,实际应用中可根据需求单独或结合使用,实现最佳性能优化。
177 0