1.查询缓存
mybatis提供查询缓存,用于减轻数据从数据库读取次数,提高数据库性能, mybatis提供一级和二级缓存
一级缓存是SqlSession级别的缓存. 操作数据库是需要构建SqlSession对象,在对象中有一个数据结构(HashMap)用于存储数据,不同的SqlSession之间的缓存区域(HashMap)是互相不影响的.
二级缓存是Mapper级别的缓存,多个SqlSession去操作同一Mapper的sql语句,多个sqlSession可以共用二级缓存,二级缓存是跨sqlSession的
一级和二级缓存用图表示为:(待加)
用缓存的原因:
若缓存中有数据就不用从数据库中获取,提高系统性能
2.一级缓存工作原理
第一次查询id为1的信息,先查询缓存中是否存在,若不存在,从数据库中查询,得到信息,将信息存储到一级缓存中
第二次发起查询id为1的信息的时候先去找缓存中是否存在,如果有,就直接从缓存中读取
如果sqlSession去执行commit操作(即增删改) 则清空sqlSession中的缓存数据,目的是让缓存中的数据是最新的信息,避免脏读,当一个sqlSession关闭结束后,该sqlSession的一级缓存也就不存在了,mybatis默认开启一级缓存.
3.二级缓存
3.1 首先要开启二级缓存
3.2 与一级缓存的区别:
二级缓存的范围更大,多个sqlSession可以共享一个useMapper的二级缓存区域,每个Mapper都有自己的区域(区域按namespace划分,如果两个mapper的names相同,则这两个mapper查询的数据放在都一个二级缓存区域),同样当mapper执行了commit() 操作后,清空该mapper在二级缓存的数据.
4.开启二级缓存
mybatis的二级缓存是在Mapper级别的,出来在SqlSessionConfig.xml(全局的配置文件)中开启,还要在相应的mapper.xml文件中开启
4.1在全局配置文件中开启
<setting name="" value="" />
cacheEnable 对在此配置下的所有cache进行全局性开/关设置 默认值为true
4.2在userMapper.xml 中开启二级缓存
<cache/> //加入这一行即可
在哪个xml文件中开启二级缓存,就只开启本文件的二级缓存
5.调用pojo类实现序列化是的接口
class User implements Serializable{
........
}
为了将缓存数据取出执行反序列化操作,因为二级缓存数据存储介质多种多样,不一定在内存中
通过close();操作将sqlSession的数据写入内存,不然写不入内存
6.禁用二级缓存
6.1禁用二级缓存
在statement中设置useCache="false" 禁用二级缓存 ,默认是true,即使用二级缓存.
如 : <select id="" resultType = "" useCache="false" />
总结:某一些总是需要更新的数据可以设置禁用二级缓存
6.2刷新缓存
设置statement 配置只不过的flushCache="true" 默认为true
总结:一般情况下,执行完commit()操作之后都需要刷新缓存,flushCache="true" 表示刷新缓存,可以避免脏读
7.mybatis整合ehcache (一个分布式缓存框架)
对数据进行集中管理(集群,不是单机),使用分布式缓存的框架
PS:不使用分布式缓存,各个服务器单独存储,不方便系统开发,mybatis无法实现分布式缓存,需要和其他分布式缓存框架进行整合
7.1整合方法
mybatis提供了一个cache接口,如果要实现自己的缓存逻辑,实现cache接口开发即可,
mybatis和ehcache整合包提供了一个cache接口的实现类(mybatis包中有cache的接口)
mybatis默认实现的cache类 PerpetualCache,需要进行更改,改成上面的实现类
mapper.xml中
<cache /> 中有type属性:指定cache接口的实现类类型,默认为PerpetualCache,要和ehcache整合,需配置ehcache的cache接口的实现类
7.2整合ehcache (加入jar包,mybatis-ehcache-1.0.2.jar,ehcache-core-2.6.5.jar)
mapper中配置cache的type属性,如下:
<cache type="org.mybatis.caches.ehcache.EhcacheCache" /> (在mybatis-ehcache,jar中有两个类,任意一个就行)
7.3加入ehcache的配置文件(在classPath下)
8.二级缓存应用的场景
8.1对于访问多的查询请求且用户对查询结果实时性要求不高的
实现方法:设置刷新间隔的时间,根据数据变化频率设置缓存刷新时间间隔flushInterval ,如30min,1h ,由mybatis每个一段时间自动清空缓存,(如果对数据实时性要求不高长时间不变的,可以通过设置时间来刷新二级缓存中的数据,到时间清空来保证数据的可能变化之后,不至于从缓存中读出错误的数值)
8.2二级缓存局限性
对细粒度的数据级别的缓存实现不好
细粒度缓存:多数据在缓存中,改变其中一个,只用这一个进入改变.
mybatis不能实现,一旦commit()操作之后,缓存中的所有数据都会清空,再将所有读入缓存,性能差.