栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mybaits基础(三)缓存

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mybaits基础(三)缓存

1、缓存的设置与使用

在Mybaits的jar包中,所有的缓存都需要实现一个接口org.apache.ibatis.cache.Cache,它具有最基础的一个实现类PerpetualCache。除此之外,Mybaits还使用了装饰器模式,在decorators文件夹内有一些装饰器,在不改变原有对象的基础上,增强扩展其功能。

缓存实现类功能说明
缓存实现类描述作用装饰条件
基本缓存缓存基本实现类默认是PerpetualCache,也可以自定义如RedisCache,EhCache等,具备基本功能的缓存类
LruCacheLRU策略的缓存当缓存达到上限时,删除最近最少使用的缓存eviction=“LRU”(默认)
FifoCacheFIFO策略的缓存当缓存达到上限时,删掉最先入队的缓存eviction=“FIFO”

SoftReference

WeakReference

待清理策略的缓存通过JVM的软引用和弱引用来实现缓存,当JVM内存不足时,会自动清理掉这些缓存,基于SoftReference和WeakReference

eviction=“SOFT”

eviction=“WEAK”

LoggingCache带日志功能的缓存比如输出缓存命中率基本
SynchronizedCache同步缓存基于Synchronized关键字实现,解决并发问题基本
BlockingCache阻塞缓存通过get/put方式中加锁,保证只有一个线程操作缓存,基于java重入锁实现block=true
SeralizedCache支持序列化的缓存将对象序列化后存到缓存中,取出时反序列化readonly=false
ScheduledCache定时调度的缓存在进行get/put/remove/getSize等操作前,判断缓存时间是否超过了设置的最长缓存时间(默认是1小时),如果是则清空缓存,即每隔一段时间清空一次缓存标签的flushInterval不为空
TransactionalCache事务缓存在二级缓存中使用,可一次存入多个缓存,移除多个缓存在TransactionCacheManager中用Map维护对应关系。

这些装饰类的使用是在对应的表Mapper文件中,使用cache标签内部的参数进行设置。 

2、一级缓存

一级缓存又叫本地缓存,默认开启,作用域是session(会话级别),这个session实际上是SQLSession,SQLSession有一个默认实现DefaultSqlSession,在DefaultSqlSession中,关键的属性有两个。

private final Configuration configuration;
private final Executor executor;

configuration是全局唯一的配置,所以只能在一个session中进行使用的一级缓存应该放Executor 中。

那么在baseExecutor 中确实包含有缓存。

public abstract class baseExecutor implements Executor {
    private static final Log log = LogFactory.getLog(baseExecutor.class);
    protected Transaction transaction;
    protected Executor wrapper;
    protected ConcurrentlinkedQueue deferredLoads;
    protected PerpetualCache localCache;
    protected PerpetualCache localOutputParameterCache;
    protected Configuration configuration;
    protected int queryStack;
    private boolean closed;

因此,作为SQLSession的一个属性,一级缓存是不能跨session的,只能在一个session内进行读取。

一级缓存有缓存失效的情况,当同一个session内执行更新操作,一级缓存会失效,这时再去读取就会让缓存失效。

一级缓存有脏数据的问题,因为一级缓存不能跨session,所以当一个session有一级缓存,另一个session更新了对应数据后,就会导致第一个session内的缓存不知道数据已经被更新,导致出现脏数据。

除此之外,如果非要关闭一级缓存,可以在settings标签中设置。当localCacheScope设置为Session时代表作用域是session,设置为Statement时代表作用域是statement,也就起不到缓存效果,算是关闭了。

 //一级缓存不生效
 //一级缓存生效
3、二级缓存

二级缓存的作用域是namespace,namespace就是命名空间,mapper文件中有一个标签就是namepace,在这一个mapper文件下的所有语句共享一个命名空间,无论是不是一个SQLSession。

二级缓存的维护对象是CachingExecutor,因为二级缓存的作用范围大于一级缓存,所以查询时需要先命中二级缓存,再命中一级缓存,最后查询数据库。

 在spring-mvc.xml文件的settings标签下,有一个内容,只有cacheEnabled设置为false时,二级缓存才不生效,无论是true还是不设置都是生效的。


    

 想要二级缓存生效,还需要在对应的mapper的xml文件中增加标签

在这个标签中,每一个属性都有自己的配置:

  1. type:配置缓存类,除了自带的类,也可以设置第三方的类进行缓存,比如redis,EH
  2. size:缓存管理的key数量
  3. eviction:选用的缓存淘汰策略
  4. flushInterval:缓存对象存活时间
  5. readonly:是否只读。如果只读,则返回的都是同一个类。非只读,就需要实现序列化,因为mybaits会为缓存对象进行序列化和反序列化创造新的类。

这样,在这个namespace中,所有的select的结果都能被二级缓存进行缓存,更新等操作则会清除缓存。如果某一个select的结果不想被缓存,可以在select标签中增加属性

useCache="false"

如果两个namespace想要共用一个二级缓存,可以在其中一个namespace中增加一个标签,cache-ref,这样就可以将共用缓存了。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/327962.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号