二级缓存(转载)

孜然风味 孜然风味     2022-08-27     349

关键词:

缓存的作用主要是用来提高hibernate的性能,可以简单的理解成一个map。使用缓存涉及到三个操作:把数据放入缓存、从缓存中取数据、删除缓存中的无效数据。

 

        一、一级缓存

        一级缓存是Session级共享的。对于一级缓存而言,所有经过Session操作的实体,不管是使用save()upadate()或者saveOrUpdate保存一个对象,还是使用load()get()list()iterate()scroll()方法获得一个对象时,该对象都将被放入一级缓存中。

  1. session = HibernateUtil.getSession();  
  2. Users users = (Users) session.get(Users.class, id);  
  3. System.out.println(users.getBirthday());  
  4. Users users2 = (Users) session.get(Users.class, id);  
  5. System.out.println(users.getName());  

        该程序当第一次查询Users对象时,hibernate会先到一级缓存中查找缓存中是否有该实体,如果有,就直接拿,否则就到数据库中去读取。这里缓存中没有,所以hibernate会到数据库中去读取数据。这里产生一条SQL语句。同时hibernate会将该实体对象放入到一级缓存中去。当第二次还查询该实体对象的时候,hibernate同样会先到一级缓存中去读,结果一级缓存中存在该实体对象,所以直接拿。故上面的程序实例只会产生一条SQL语句。

        在Session调用flush()方法或者close()方法之前,这些对象都会一直缓存在一级缓存中。

        由于一级缓存不能控制缓存的对象数据,所以在大批量操作数据的时候可能会造成内存溢出。

        清除缓存有两个方法:evil()clear()。其中evil()用于清除一条记录,它接受一个持久化类参数。Clear用于清除session里面所有的记录。

 

 

        二、二级缓存

        SessionFactory级别的二级缓存是全局的,应用的所有Session都共享这个二级缓存。但是二级缓存默认是关闭的,必须由程序显示开启

        使用二级缓存一般有如下步骤:

        1、在hibernate.cfg.xml中开启二级缓存

  1. <property name="cache.use_second_level_cache">true</property>  

        2、设置二级缓存的实现类

        实际应用中一般不需要我们自己实现缓存,直接使用第三方提供的缓存即可。

  1. <property name="cache.provider_class">org.hibernate.cache.EHCacheProvider</property>  
  1. Hibernate 3所支持的缓存实现  

技术分享        3、复制二级缓存的JAR包。

        使用第三方提供的缓存就必须将相应的JAR包复制到应用的类加载路径中去。这里我采用的是EHCache

        注意在使用EHCache的时候,要将入下两个JAR包也要加载到项目应用中:commons-logginbackport-util-concurrent

        4、将缓存实现所需要的配置文件添加到系统的类加载路径中。对于EHCache缓存而言,它需要一个ehcache.xml配置文件。

       配置文件代码如下:

  1. <ehcache>  
  2.     <defaultCache  
  3.         maxElementsInMemory="10000"                  
  4.         eternal="false"  
  5.         timeToIdleSeconds="120"  
  6.         timeToLiveSeconds="120"  
  7.         overflowToDisk="true"  
  8.         />  
  9. </ehcache>  

        5、设置对那些实体类。实体的那些集合属性开启二级缓存。

        在这里一般有如下两种方法:

           1)、修改要使用缓存的映射文件。在持久化映射文件的<class.../>元素、或者<set.../><list.../>等集合元素内使用<cache.../>元素指定缓存策略

  1. <hibernate-mapping package="com.hibernate.domain">  
  2.     <class name="Users">  
  3.         <cache usage="read-only"/>    <!-- 缓存策略为只读 -->  
  4.         <id name="id">  
  5.             <generator class="native" />  
  6.         </id>  
  7.   
  8.         <property name="birthday" />  
  9.           
  10.         <!-- 映射组件元素 -->  
  11.         <component name="name">  
  12.             <!-- 映射组件的name属性指向包含实体 -->  
  13.             <property name="firstName" column="first_name"/>  
  14.             <property name="lastName" column="last_name"/>  
  15.         </component>  
  16.     </class>  
  17. </hibernate-mapping>  

           2)、在hibernate.cfg.xml文件中使用<class-cache.../>或者<collection-cache.../>元素对知道那个的持久化类、集合属性启用二级缓存

  1. <class-cache usage="read-only" class="com.hibernate.domain.Users"/>  

         6测试程序

  1. public void query(int id){  
  2.     Session session = null;  
  3.     try {  
  4.         session = HibernateUtil.getSession();  
  5.         Users users = (Users) session.get(Users.class, id);  
  6.         System.out.println(users.getBirthday());  
  7.     } finally{  
  8.         if(session!=null)  
  9.           session.close();  
  10.     }  
  11.       
  12.     try {  
  13.         session = HibernateUtil.getSession();  
  14.         Users users = (Users) session.get(Users.class, id);  
  15.         System.out.println(users.getName());  
  16.     }finally{  
  17.         if(session!=null)  
  18.           session.close();  
  19.     }  
  20. }  

        当第一次查询Users实体之后,SessionFactory会将该实体缓存在二级缓存中,在这里先关闭session1然后重新创建session,在一次查询Users实体时,程序就可以直接使用缓存中已经存在的Users实体了。这里只产生一条SQL查询语句。

技术分享 

        2.1、缓存策略

        二级缓存存在如下四种缓存策略:read-onlyread-writenonstrict-read-writetransaction

        read-only:只读策略。如果应用程序只需要读取持久化实体的对象,无须对其进行修改,那么就可以对其设置为"只读"缓存策略。这是最简单,也是实用性最好的方法。甚至在集群中,它也能完美地运作。

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

        nonstrict-read-write:非严格读/写策略。如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离, 那么比较适合使用非严格读/写缓存策略。

        transaction:事物缓存。Hibernate的事务缓存策略提供了全事务的缓存支持。这样的缓存只能用于JTA环境中,你必须指定 为其hibernate.transaction.manager_lookup_class属性。

 

        没有一种缓存提供商能够支持上列的所有缓存并发策略。下表中列出了各种提供器、及其各自适用的并发策略。

技术分享

        

        2.2、管理缓存

        对于二级缓存而言,SessionFactory提供了许多方法用于清除缓存中实例、整个类、集合实例或者整个集合。

  1. sessionFactory.evict(Users.class, id); //清除指定id的Users对象  
  2.   
  3. sessionFactory.evict(Users.class);                         // 清除所有的Users对象  
  4.   
  5. sessionFactory.evictCollection("Users.name",id); //清除指定id的Users所关联集合属性  
  6.   
  7. sessionFactory.evictCollection("Users.name"); //清除所有Users所关联集合属性  

        SessionFactory还提供了一个getCache()方法,该方法返回一个Cache对象,通过该对象即可操作二级缓存中的实体、集合等。

 

        CacheMode参数用于控制具体的Session如何与二级缓存进行交互。

        CacheMode.NORMAL - 从二级缓存中读、写数据。

        CacheMode.GET - 从二级缓存中读取数据,仅在数据更新时对二级缓存写数据。

        CacheMode.PUT - 仅向二级缓存写数据,但不从二级缓存中读数据。

        CacheMode.REFRESH - 仅向二级缓存写数据,但不从二级缓存中读数据。通过 hibernate.cache.use_minimal_puts的设置,强制二级缓存从数据库中读取数据,刷新缓存内容。

 

        如果需要查看二级缓存或查询缓存区域的内容,可以使用Hibernate的统计(Statistics) API

        为了开启二级缓存的统计功能,需要在hibernate.cfg.xml文件中进行配置。

  1. <property name="generate_statistics">true</property>  
  2. <property name="cache.use_structured_entries">true</property>  

        可以通过如下方式查看二级缓存的内容

  1. Map cacheEntries = HibernateUtil.getSessionFactory().getStatistics()  
  2.                   .getSecondLevelCacheStatistics("com.hibernate.domain.Users").getEntries();  
  3. System.out.println(cacheEntries);  


       

         2.3、查询缓存

        一级、二级缓存都是对整个实体进行缓存,它不会缓存普通属性,如果想对普通属性进行缓存,则可以使用查询缓存。

        使用查询缓存时,不仅需要所使用的HQL语句、SQL语句相同,还要求所传入的参数也相同。

        要使用查询缓存就需要在hibernate.cfg.xml中开启查询缓存:

  1. <property name="cache.use_query_cache">true</property>  

        该设置将会创建两个缓存区域 一个用于保存查询结果集; 另一个则用于保存最近查询的一系列表的时间戳。 

        如若需要进行缓存,请调用 Query.setCacheable(true)方法,该方法用于开启查询缓存。这个调用会让查询在执行过程中时先从缓存中查找结果, 并将自己的结果集放到缓存中去。

        如果你要对查询缓存的失效政策进行精确的控制,你必须调用Query.setCacheRegion()方法, 为每个查询指定其命名的缓存区域。

    1. public void cacheQuery(){  
    2.     Session  session = HibernateUtil.getSession();  
    3.     List list = session.createQuery("from User u where u.id=:id")  
    4.                 .setInteger("id", 2)  
    5.                 .setCacheable(true)  
    6.                 .setCacheRegion("name")  
    7.                 .list();  
    8.   

mybatis缓存之二级缓存

二级缓存(全局缓存):基于namespace级别的缓存,一个namespace对应一个二级缓存。工作机制:一个会话,查询一条数据,这条数据会放在当前会话的一级缓存中;如果会话关闭,该会话对应的一级缓存就消失了;可以使用二级缓... 查看详情

mybatis的二级缓存讲解(代码片段)

目录1、二级缓存的定义2、二级缓存扩展性需求3、二级缓存的结构4、SynchronizedCache线程同步缓存区5、LoggingCache统计命中率以及打印日志6、ScheduledCache过期清理缓存区7、LruCache(最近最少使用)防溢出缓存区8、FifoCache(先进先出)防溢... 查看详情

mybatis缓存,包含一级缓存与二级缓存,包括ehcache二级缓存

...batis缓存概要①、mybatis的缓存有两种,分别是一级缓存和二级缓存。两者都属于查询缓存,也就是只有执行查询操作的时候才起缓存作用,对于增删改操作无效。②、一级缓存默认开启,二级缓存默认关闭。③、两者都可以使用... 查看详情

mybatis的二级缓存

文章目录MyBatis的二级缓存MyBatis默认是开启一级缓存的开启MyBatis的二级缓存为什么要开启二级缓存在mybatis的配置文件中进行配置在对应的mapper映射文件中声明相关的DO对象需要实现序列化测试动态代理接口执行更新方法后会清空... 查看详情

二级缓存

 看图说话二级缓存原理图:每次从二级缓存中取出的对象,都是一个新的对象。**************************************************************************************所需的jar包关键就是在大配置中:  查看详情

使用redis做mybaties的二级缓存-mybatis二级缓存小心使用

 Mybatis默认对二级缓存是关闭的,一级缓存默认开启;下面就说说为什么使用二级缓存需要注意:    二级缓存是建立在同一个namespace下的,如果对表的操作查询可能有多个namespace,那么得到的数据就是错误的... 查看详情

mybatis框架查询缓存-二级缓存原理

二级缓存原理1.原理首先看图首先开启mybatis的二级缓存。sqlSession1去查询用户id为1的用户信息,查询到用户信息会将查询数据存储到二级缓存中。如果SqlSession3去执行相同mapper下sql,执行commit提交,清空该mapper下的二级缓存区域... 查看详情

mybatis0209二级缓存

1.1二级缓存1.1.1原理mybatis和spring整合后一级缓存就没有了,sqlSession在不关闭的前提下2次查询就会从缓存中取,一级缓存缓存在sqlSession对象里面,当多用户查询的时候就用到二级缓存了。UserMapper缓存:会把根据id和根据name查询... 查看详情

什么是一级缓存,什么是二级缓存?

高速缓存分为一级缓存(即L1Cache)和二级缓存(即L2Cache)。CPU在运行时首先从一级缓存读取数据,然后从二级缓存读取数据,然后从内存和虚拟内存读取数据,因此高速缓存的容量和速度直接影响到CPU的工作性能。一级缓存都... 查看详情

一级缓存与二级缓存

...别的缓存由hibernate管理的,一般情况下无需进行干预;第二级别的缓存是SessionFactory级别的缓存,它是属于进程范围或群集范围的缓存。这一级别的缓存可以进行配置和更改,并且可以动态加载和卸载。Hibernate还为查询结果提供... 查看详情

mybatis——一级缓存二级缓存

...效率。●MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存  ○ 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)  ○ 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。 ... 查看详情

谁给我解释一下一级缓存和二级缓存啊~

参考技术A无论是一级还是二级缓存都可以看成一个高性能的内存,性能要比内存强很多,可以看成是几个性能数量级的内存。而且一级缓存要比二级更为高效强大。他们都是暂时寄存数据,等待CPU处理。但是一级缓存的造价昂... 查看详情

mybatis开启二级缓存小记

mybatis开启二级缓存小记1.开启二级缓存  和一级缓存默认开启不一样,二级缓存需要我们手动开启  首先在全局配置文件mybatis-configuration.xml文件中加入如下代码:<!--开启二级缓存--><settings><settingname="cacheEnable... 查看详情

一级缓存和二级缓存有啥区别

...级缓存是同速缓存,和CPU运行速度相同,价格极高,容量小,二级缓存是半速缓存,以CPU一半的速度运行,价格较低,容量稍大.CPU优先从一级缓存读取数据,一级缓存优先从二级缓存读取数据,二级缓存从3.4级缓存或者内存读取数据参考技... 查看详情

何时以及如何使用休眠二级缓存?

】何时以及如何使用休眠二级缓存?【英文标题】:Whenandhowtousehibernatesecondlevelcache?【发布时间】:2011-10-2621:28:27【问题描述】:我无法理解休眠何时命中二级缓存以及何时使缓存无效。这是我目前理解的:二级缓存存储会话之... 查看详情

mybatis一级缓存与二级缓存

...作  3.session.close();//不是同一个Session对象了 MyBatis二级缓存  需要配置<cache></cache>  是一个映射文件级的缓存 查看详情

hibernate二级缓存

一、定义:二级缓存是进程或集群范围内的缓存,可以被所有的Session共享,是可配置的插件二、二级缓存原理图 解析:每次从二级缓存中取出的对象,都是一个新的对象。 三、配置步骤如下:同理:以员工类和部门类... 查看详情

mybatis-一级缓存与二级缓存

...轻数据压力,提高数据库性能。mybaits提供一级缓存,和二级缓存。 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之... 查看详情