MyBatis学习总结(十):MyBatis的一级缓存和二级缓存

1、缓存的介绍

(1)什么是缓存?

原义是指访问速度比一般随机存取存储器快的一种RAM,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。在编程中所谓的缓存,就是将程序
或系统经常要调用的对象(临时数据)存在内存中,从而使得其在使用时可以快速调用,不必再去创建新的重复的实例。

(2)缓存的意义是什么?

使用缓存是为了减少和数据库的交互次数,这样做可以减少系统的开销,提高执行效率。

(3)适合缓存的数据

适用于缓存的数据:经常查询并且不经常改变的,并且的数据的正确与否对最终结果影响不大的。

不适用于缓存的数据:经常改变的数据,数据的正确与否对最终结果影响很大的。

2、一级缓存

MyBatis的一级缓存其实就是一个sqlsession级别的,意思就是sqlsession只能访问自己的一级缓存的数据。一级缓存查询存在于每一个的sqlsession类的实例对象中,当第一次查询某一个数据时候,sqlsession类的实例对象会将该数据存入到一级缓存。这样可以在没有收到改变该数据的请求之前,我们所查询数据都是从缓存中去获取的,而不是从数据库中去取数据,这样就大大减少数据库的频繁查询,导致效率降低的原因。当我们再次查询时,会在SqlSession中是否存在,有的话直接使用。当SqlSession对象消失时,MyBatis中的一级缓存信息也会消失。

image

触发清空一级缓存的情况:

  • clearCache():清空缓存
  • 数据发生变化 :一级缓存是SqlSession范围的缓存,当调用SqlSession的修改、删除、添加、commit()、close()等方法时,就会清空一级缓存。

一级缓存的范围有SESSION和STATEMENT两种,默认是SESSION,如果不想使用一级缓存,可以把一级缓存的范围指定为STATEMENT,这样每次执行完一个Mapper中的语句后都会将一级缓存清除。
如果需要更改一级缓存的范围,可以在Mybatis的配置文件中,在下通过localCacheScope指定。
如下:

<setting name="localCacheScope" value="STATEMENT"/>

3、二级缓存

二级缓存指的就是同一个namespace下的mapper,二级缓存中,也有一个map结构,这个区域就是一级缓存区域。一级缓存中的key是由sql语句、条件、statement等信息组成一个唯一值。一级缓存中的value,就是查询出的结果对象。

image

使用步骤:

(1)在SqlMapperConfig.xml中开启二级缓存。

<setting name="cacheEnabled" value="true" />

(2)在mapper映射文件中开启二级缓存。

<cache eviction="FIFO" flushInterval="60000" size="512" 
readOnly="true"/>

属性说明:

参数名 属性
eviction 收回策略
flushInterval 刷新间隔
size 引用数目
readOnly 只读

关于eviction的各个参数属性:

参数名 属性
eviction="LRU" 最近最少使用的:移除最长时间不被使用的对象。 (默认)
eviction="FIFO" 先进先出:按对象进入缓存的顺序来移除它们。
eviction="SOFT" 软引用:移除基于垃圾回收器状态和软引用规则的对象。
eviction="WEAK" 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

(3) 让当前操作支持二级缓存——select标签中配置(useCache="true")

示例:

(1)在SqlMapperConfig.xml中开启二级缓存。

<setting name="cacheEnabled" value="true" />

(2)在userMapper映射文件中开启二级缓存。

 <cache></cache>

(3)让当前操作支持二级缓存

<!-- 根据id查询用户   -->
    <select id="findById" parameterType="Integer" resultType="com.day1.entity.User" useCache="true">
        select * from t_user where id = #{id}
    </select>

经测试,执行结果如下: 

总结:

mybatis的的一级缓存是SqlSession级别的缓存,一级缓存缓存的是对象,当SqlSession提交、关闭以及其他的更新数据库的操作发生后,一级缓存就会清空。

二级缓存是SqlSessionFactory级别的缓存,同一个SqlSessionFactory产生的SqlSession都共享一个二级缓存,二级缓存中存储的是数据,当命中二级缓存时,通过存储的数据构造对象返回。查询数据的时候,查询的流程是二级缓存>一级缓存>数据库 

4、错误总结

错误信息:Cause: org.apache.ibatis.cache.CacheException: Error serializing object.  Cause: java.io.NotSerializableException: com.day1.entity.User

原因:实体类User未实现序列化接口。MyBatia中的二级缓存中存放的是数据,需要通过反序列化来创建对象。

解决方案:让User实现序列化接口。

猜你喜欢

转载自blog.csdn.net/weixin_47382783/article/details/113842001