Mybatis中的缓存
1 什么是缓存
缓存就是存在于内存中的临时数据,当下次使用数据的时候,可以直接获取数据,不用再从数据库中获取数据。
2 为什么使用缓存
减少与数据库的交互,提高执行效率
适用于缓存的数据:
- 经常查询
- 不经常修改
- 数据的正确与否对最终结果影响不大
经常改变的数据,以及数据的正确与否对结果影响很大的,例如银行汇率、股市牌价等不适用缓存
服务端到数据库是要进行网络交互。缓存可以减少服务端和数据库的交互,即减轻数据库压力,提高数据库的性能,缓存主要是用于查询缓存。
3 脏数据:
什么是脏数据?举例:
查询id=1查询到用户信息,放入到缓存,后续对id=1的查询就可以直接查询缓存数据。对id = 1 的数据进行变更(用户id=1的电话做了变更),数据的变更数据库。变更后,在查询id=1的时候,查询缓存,缓存中就存在为更新的旧数据
使用缓存时注意:一定要避免脏数据问题
缓存更新时机:
缓存数据做变更?涉及缓存的更新时机:
- 查询操作时,首先访问缓存,当缓存没有对应数据时,在查询数据,将数据库的中数据查询到后,插入到缓存中,后续的插叙就可以直接访问缓存
- 在变更操作时(修改,删除等)将数据变更到数据库时,直接将对应的缓存信息清空
- 再次查询时,访问缓存没有数据,就查询数据库将数据库返回的结果放入缓存,通过该更新机制能够保证缓存数据是最新的数据
4 缓存的实现方式:
1、在单实例服务器下,可以在当前服务代码中通过添加HashMap集合实例来充当缓存
在集群服务中,本地缓存(HashMap)无法将缓存数据共享给其他的服务器
2、在多服务器下,需要通过缓存共享的形式来缓存数据,使用缓存服务器处理,缓存服务器的代表:Redis,memCache等
5 Mybatis中的一级缓存和二级缓存
一级缓存:它指的时Mybatis中SqlSession对象的缓存。当我们执行查询后,查询结果会同时存入到SqlSession为我们提供的一块区域中。
该区域结构是一个Map。当我们再次查询同样的数据,mybatis会先去SqlSession中查询是否有,有的话直接拿出来使用。
当SqlSession对象消失时,mybatis的一级缓存也就消失了。
这里需要注意:当调用SqlSession的修改、添加、删除、
commit()
、close()
等方法时,就会清空一级缓存
二级缓存:指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
二级缓存的使用步骤:
- 让Mybatis框架支持二级缓存,在总配置.xml 中配置
- 让当前映射文件支持二级缓存,在类配置.xml 中配置
- 让当前的操作支持二级缓存,在select标签中配置
同时需要注意:二级缓存中存放的内容是数据,不是对象。
例如开启二级缓存后,新建两个SqlSession对象,调用方法返回两个User对象,虽然其内容一样,但是并不是一个对象。
6 Mybatis中一二级缓存的实现
6.1 一级缓存实现
Mybatis是默认支持一级缓存
<settings>
<!--开启缓存的开关-->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
6.2 二级缓存实现
二级缓存是Mapper级别的缓存,默认情况下二级缓存是关闭的,同一个Mapper下不同的sqlSession是可以共享二级缓存,不同Mapper缓存是相互隔离的。
1、在全局配置文件中打开二级缓存的开关:
<settings>
<!--开启二级缓存的开关-->
<setting name="cacheEnabled" value="true"/>
</settings>
2、将映射的pojo类实现序列化
public class Student implements Serializable
3、在mapper配置文件中添加cache标签
<mapper namespace="com.tulun.dao.StudentMapper1">
<!--开启本Mapper的二级缓存-->
<cache></cache>
Cache的参数说明:
<!--
cache参数说明:
flushInterval(缓存刷新间隔)单位毫秒,默认情况下不设置,在变更操作时,进行缓存刷新
size:(引用次数)记录缓存对象的数量 默认值1024
readOnly(只读)参数为true:false 表示缓存的数据对象实例是不能被修改
eviction:缓存失效的策略 默认LRU
LRU:最近最少使用的:移除最长时间不使用的
FIFO:先进先出,按照缓存对象的顺序来淘汰
SOFT:软引用
WEAK:弱引用
-->
<cache eviction="LRU" readOnly="true" flushInterval="10000" size="12"></cache></cache>
Cache的配置禁用
useCache=“false”
在statement上配置useCache=“false”,禁用的是二级缓存