IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Mybaits基础(三)缓存 -> 正文阅读

[Java知识库]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小时),如果是则清空缓存,即每隔一段时间清空一次缓存<mapper>的<cache>标签的flushInterval不为空
TransactionalCache事务缓存在二级缓存中使用,可一次存入多个缓存,移除多个缓存在TransactionCacheManager中用Map维护对应关系。

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

<cache type="org.apache.ibatis.cache.impl.PerpetualCache" 
           size="1024" eviction="LRU" flushInterval="120000" readOnly="false"/>

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<BaseExecutor.DeferredLoad> 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,也就起不到缓存效果,算是关闭了。

<setting name="localCacheScope" value="STATEMENT"/> //一级缓存不生效
<setting name="localCacheScope" value="SESSION"/> //一级缓存生效

3、二级缓存

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

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

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

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

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

<cache type="org.apache.ibatis.cache.impl.PerpetualCache"
           size="1024" eviction="LRU" flushInterval="120000" readOnly="false"/>

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

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

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

useCache="false"

<select id="queryUser" parameterType="java.lang.Long" 
    resultMap="BaseResultMap" useCache="false">
    select
        <include refid="Base_Column_List" />
    from user
</select>

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

<cache-ref namespace=""/>

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-17 11:52:07  更:2021-10-17 11:54:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:04:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码