Mybatis的缓存

1、关于缓存的介绍

Mybatis一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询到的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。

Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

如果二级缓存没有取到,再从一级缓存中找,如果一级缓存也没有,从数据库查询。

2、关于一级缓存

     1、关于一级缓存的清空

一级缓存区域是根据SqlSession为单位划分的。每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。Mybatis内部存储缓存使用一个HashMap,Key为hashCode+sqlId+sql语句。value为从查询出来映射生成的Java对象。

sqlSession执行insertupdatedelete等操作commit提交后会清空缓存区域

 2、关于一级缓存的测试

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1.            //获取session  
  2. SqlSession session = sqlSessionFactory.openSession();  
  3. //获限mapper接口实例  
  4. UserMapper userMapper = session.getMapper(UserMapper.class);  
  5. //第一次查询  
  6. User user1 = userMapper.findUserById(1);  
  7. System.out.println(user1);  
  8.               //第二次查询,由于是同一个session则不再向数据发出语句直接从缓存取出  
  9. User user2 = userMapper.findUserById(1);  
  10. System.out.println(user2);  
  11.               //关闭session  
  12. session.close();  

 3、关于一级缓存清空的测试

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1.            //获取session  
  2. SqlSession session = sqlSessionFactory.openSession();  
  3. //获限mapper接口实例  
  4. UserMapper userMapper = session.getMapper(UserMapper.class);  
  5. //第一次查询  
  6. User user1 = userMapper.findUserById(1);  
  7. System.out.println(user1);  
  8. //在同一个session执行更新  
  9. User user_update = new User();  
  10. user_update.setId(1);  
  11. user_update.setUsername("李奎");  
  12. userMapper.updateUser(user_update);  
  13. session.commit();  
  14. //第二次查询,虽然是同一个session但是由于执行了更新操作session的缓存被清空,这里重新发出sql操作  
  15. User user2 = userMapper.findUserById(1);  
  16. System.out.println(user2);  

3、关于二级缓存

            1、关于二级缓存的介绍

二级缓存区域是根据mappernamespace划分的,相同namespace的mapper查询数据放在同一个区域,如果使用mapper代理方法每个mapper的namespace都不同,此时可以理解为二级缓存区域是根据mapper划分。

每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象。

sqlSession执行insertupdatedelete等操作commit提交后会清空缓存区域。

           2、开启二级缓存

                                        描述

允许值

     默认值

cacheEnabled:      对在此配置文件下的所有cache 进行全局性开/关设置。

true|false

    true

 

在核心配置文件SqlMapConfig.xml中加入

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <setting name="cacheEnabled" value="true" />  

要在你的Mapper映射文件中添加一行:  <cache /> ,表示此mapper开启二级缓存。

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <mapper namespace="com.mybatis.mapper.UserMapper">  
  2.   
  3.     <!--开启二级缓存 -->  
  4.     <cache />  
  5. </mapper>  
          3、实现序列化

二级缓存需要查询结果映射的pojo对象实现java.io.Serializable接口实现序列化和反序列化操作,注意如果存在父类、成员pojo都需要实现序列化接口。

         4、二级缓存的测试

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1.               //获取session1  
  2. SqlSession session1 = sqlSessionFactory.openSession();  
  3. UserMapper userMapper = session1.getMapper(UserMapper.class);  
  4. //使用session1执行第一次查询  
  5. User user1 = userMapper.findUserById(1);  
  6. System.out.println(user1);  
  7. //关闭session1  
  8. session1.close();  
  9. //获取session2  
  10. SqlSession session2 = sqlSessionFactory.openSession();  
  11. UserMapper userMapper2 = session2.getMapper(UserMapper.class);  
  12. //使用session2执行第二次查询,由于开启了二级缓存这里从缓存中获取数据不再向数据库发出sql  
  13. User user2 = userMapper2.findUserById(1);  
  14. System.out.println(user2);  
  15. //关闭session2  
  16. session2.close();  

         5、禁用二级缓存

在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">  

       6、刷新缓存

如果sqlsession操作commit操作,对二级缓存进行刷新(全局清空)。

设置statement配置中的flushCache="true" 属性,默认情况下为true即刷新缓存,如果改成false则不会刷新。

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">  

4、mybatis Cache参数

mybatis的cache参数只适用于mybatis维护缓存。

flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。

size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。

readOnly(只读)属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。

如下例子:

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <cache  eviction="FIFO"  flushInterval="60000"  size="512"  readOnly="true"/>  

这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会导致冲突。可用的收回策略有, 默认的是 LRU:

1.      LRU – 最近最少使用的:移除最长时间不被使用的对象。

2.      FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

3.      SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

4.      WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

5、mybatis整合ehcache

      1、ehcache的介绍

            EhCache 是一个纯Java的进程内缓存框架,是一种广泛使用的开源Java分布式缓存,具有快速、精干等特点,是hibernate中默认的CacheProvider。

      2、mybatis整合encache的原理

            mybatis提供二级缓存Cache接口,如下:


           它的默认实现类:


通过实现Cache接口可以实现mybatis缓存数据通过其它缓存数据库整合,mybatis的特长是sql操作,缓存数据的管理不是mybatis的特长,为了提高缓存的性能将mybatis和第三方的缓存数据库整合,比如ehcache、memcache、Redis等。

     3、mybatis整合ehcache的步骤

1、引入缓存的依赖包


maven坐标:

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <dependency>  
  2.     <groupId>org.mybatis.caches</groupId>  
  3.     <artifactId>mybatis-ehcache</artifactId>  
  4.     <version>1.0.2</version>  
  5. </dependency>  

2、引入缓存的配置文件

classpath下添加:ehcache.xml

内容如下:

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">  
  3.     <diskStore path="F:\develop\ehcache" />  
  4.     <defaultCache   
  5.         maxElementsInMemory="1000"   
  6.         maxElementsOnDisk="10000000"  
  7.         eternal="false"   
  8.         overflowToDisk="false"   
  9.         timeToIdleSeconds="120"  
  10.         timeToLiveSeconds="120"   
  11.         diskExpiryThreadIntervalSeconds="120"  
  12.         memoryStoreEvictionPolicy="LRU">  
  13.     </defaultCache>  
  14. </ehcache>  

属性说明:

 diskStore:指定数据在磁盘中的存储位置。

 defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略

以下属性是必须的:

maxElementsInMemory - 在内存中缓存的element的最大数目

maxElementsOnDisk - 在磁盘上缓存的element的最大数目,若是0表示无穷大

 eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSecondstimeToLiveSeconds判断

overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上

以下属性是可选的:

3、开启ehcache缓存

EhcacheCache是ehcache对Cache接口的实现


修改mapper.xml文件,在cache中指定EhcacheCache

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>  

根据需求调整缓存参数:

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <cache type="org.mybatis.caches.ehcache.EhcacheCache" >   
  2.         <property name="timeToIdleSeconds" value="3600"/>  
  3.         <property name="timeToLiveSeconds" value="3600"/>  
  4.         <!-- 同ehcache参数maxElementsInMemory -->  
  5.         <property name="maxEntriesLocalHeap" value="1000"/>  
  6.         <!-- 同ehcache参数maxElementsOnDisk -->  
  7.         <property name="maxEntriesLocalDisk" value="10000000"/>  
  8.         <property name="memoryStoreEvictionPolicy" value="LRU"/>  

  1. </cache>  

6、源码下载


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值