Mybatis-缓存
缓存原理
一级缓存(本地缓存)
sqlSession级别的缓存(map)
工作机制
与数据库同一次会话期间查询到的数据会放在本地缓存中,以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库
一级缓存失效情况
- sqlSession不同;(多个sqlSession对象发出相同的查询请求,都会从数据库查询)
- sqlSession相同,查询条件不同;(都没查询过这个条件,当前缓存中肯定是没有啦,所以需要向数据库发出查询)
- sqlSession相同,两次查询之间执行了增删改操作;(做过增删改可能涉及脏数据,所以底层session.clear()清除了缓存)
- sqlSession相同,手动清除了一级缓存(session.clear()
二级缓存(全局缓存)
基于namespace级别的缓存,一个namespace(mapper文件)对应一个二级缓存
工作机制
- 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中
- 如果会话关闭,一级缓存中的数据会被保存到二级缓存中(只有会话提交或者关闭以后,一级缓存中的数据才会转移到二级缓存中);
- 新的会话查询信息,就可以参照二级缓存中的内容
- 不同namespace查出的数据会放在自己对应的缓存中(map)
使用二级缓存
- 开启全局二级缓存配置:<setting name="cacheEnabled" value="true"/>
- 在mapper.xml中配置<cache></cache>即可使用二级缓存
- 我们的POJO需要实现序列化接口,因为在二级缓存中为了数据安全,给用户的数据要经过序列化和反序列化的
和缓存有关的设置/属性
- cacheEnabled=true;默认开启二级缓存
- localCacheScope:本地缓存作用域,默认SESSION将当前会话的所有数据保存在会话缓存中;STATEMENT可以禁用一级缓存
- 每个select标签都有useCache="true":如果设为false二级缓存不使用,一级缓存依然使用
- 每个增删改标签都有flushCache="true":(一级二级缓存都会清除)
- sqlSession.clearCache();只是清除当前session的一级缓存;
cache相关的属性
<cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"></cache>
- eviction:缓存的回收策略(默认的是 LRU):flushInterval:缓存刷新间隔(缓存多长时间清空一次,默认不清空,设置一个毫秒值)
- LRU – 最近最少使用的:移除最长时间不被使用的对象。
- FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
- SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
- WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
- flushInterval:缓存刷新间隔(缓存多长时间清空一次,默认不清空,设置一个毫秒值)
- readOnly:是否只读size:缓存存放多少元素;
- true:只读;mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据;mybatis为了加快获取速度,直接就会将数据在缓存中的引用交给用户。不安全,速度快
- false:非只读:mybatis觉得获取的数据可能会被修改;mybatis会利用序列化&反序列的技术克隆一份新的数据给你。安全,速度慢
- type="":指定自定义缓存的全类名;实现Cache接口即可
整合ehcache
mybatis的cache只是用map来实现的,衍生考虑到会发生的问题:
- 如果我们的应用一直开启是否存在内存溢出的问题?
- 如果应用关了我们的二级缓存都没有了,下次开启用户访问查询则又要查询数据库
- 如果我们只是想修改一条数据记录,但update则会把所属的namespace(或者说所有的,没测试)的所有缓存清空
所以有必要用缓存数据库来代替mybatis的二级缓存,我们只需要实现mybatis提供的cache接口即可
- 下载ehcache.jar及mybatis-ehcache适配包、slf4j-api.jar及slf4j-log4j的适配包
- 类路径下配置ehcache.xml
- mapper.xml中使用自定义缓存
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache> <!-- 引用缓存:namespace:指定和哪个名称空间下的缓存一样 --> <cache-ref namespace="com.atguigu.mybatis.dao.EmployeeMapper"/>
ehcache缓存的数据存放在本地磁盘中