MyBatis基础模块-缓存模块

server/2025/3/1 7:24:57/

缓存模块

MyBatis作为一个强大的持久层框架,缓存是其必不可少的功能之一,Mybatis中的缓存分为一级缓存和二级缓存。但本质上是一样的,都是使用Cache接口实现的。缓存位于 org.apache.ibatis.cache包下。

image.png

通过结构我们能够发现Cache其实使用到了装饰器模式来实现缓存的处理。首先大家需要先回顾下装饰器模式的相关内容哦。我们先来看看Cache中的基础类的API

// 煎饼加鸡蛋加香肠
“装饰者模式(Decorator Pattern)是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能)。”

image.png

1. Cache接口

Cache接口是缓存模块中最核心的接口,它定义了所有缓存的基本行为,Cache接口的定义如下:
public interface Cache {/*** 缓存对象的 ID* @return The identifier of this cache*/String getId();/*** 向缓存中添加数据,一般情况下 key是CacheKey  value是查询结果* @param key Can be any object but usually it is a {@link CacheKey}* @param value The result of a select.*/void putObject(Object key, Object value);/*** 根据指定的key,在缓存中查找对应的结果对象* @param key The key* @return The object stored in the cache.*/Object getObject(Object key);/*** As of 3.3.0 this method is only called during a rollback* for any previous value that was missing in the cache.* This lets any blocking cache to release the lock that* may have previously put on the key.* A blocking cache puts a lock when a value is null* and releases it when the value is back again.* This way other threads will wait for the value to be* available instead of hitting the database.*   删除key对应的缓存数据** @param key The key* @return Not used*/Object removeObject(Object key);/*** Clears this cache instance.* 清空缓存*/void clear();/*** Optional. This method is not called by the core.* 缓存的个数。* @return The number of elements stored in the cache (not its capacity).*/int getSize();/*** Optional. As of 3.2.6 this method is no longer called by the core.* <p>* Any locking needed by the cache must be provided internally by the cache provider.*  获取读写锁* @return A ReadWriteLock*/default ReadWriteLock getReadWriteLock() {return null;}}

Cache接口的实现类很多,但是大部分都是装饰器,只有PerpetualCache提供了Cache接口的基本实现。

image.png

2. PerpetualCache

PerpetualCache在缓存模块中扮演了ConcreteComponent的角色,其实现比较简单,底层使用HashMap记录缓存项,具体的实现如下:

/*** 在装饰器模式用 用来被装饰的对象* 缓存中的  基本缓存处理的实现* 其实就是一个 HashMap 的基本操作* @author Clinton Begin*/
public class PerpetualCache implements Cache {private final String id; // Cache 对象的唯一标识// 用于记录缓存的Map对象private final Map<Object, Object> cache = new HashMap<>();public PerpetualCache(String id) {this.id = id;}@Overridepublic String getId() {return id;}@Overridepublic int getSize() {return cache.size();}@Overridepublic void putObject(Object key, Object value) {cache.put(key, value);}@Overridepublic Object getObject(Object key) {return cache.get(key);}@Overridepublic Object removeObject(Object key) {return cache.remove(key);}@Overridepublic void clear() {cache.clear();}@Overridepublic boolean equals(Object o) {if (getId() == null) {throw new CacheException("Cache instances require an ID.");}if (this == o) {return true;}if (!(o instanceof Cache)) {return false;}Cache otherCache = (Cache) o;// 只关心IDreturn getId().equals(otherCache.getId());}@Overridepublic int hashCode() {if (getId() == null) {throw new CacheException("Cache instances require an ID.");}// 只关心IDreturn getId().hashCode();}}

然后我们可以来看看cache.decorators包下提供的装饰器。他们都实现了Cache接口。这些装饰器都在PerpetualCache的基础上提供了一些额外的功能,通过多个组合实现一些特殊的需求。

3.BlockingCache

通过名称我们能看出来是一个阻塞同步的缓存,它保证只有一个线程到缓存中查找指定的key对应的数据。

public class BlockingCache implements Cache {private long timeout; // 阻塞超时时长private final 

http://www.ppmy.cn/server/171494.html

相关文章

wordpress子分类调用父分类名称和链接的3种方法

专为导航而生&#xff0c;在wordpress模板制作过程中常常会在做breadcrumbs导航时会用到&#xff0c;子分类调用父分类的名称和链接&#xff0c;下面这段简洁的代码&#xff0c;可以完美解决这个问题。 <?php echo get_category_parents( $cat, true, &raquo; ); ?…

【电路笔记】-MOD计数器

MOD计数器 文章目录 MOD计数器1、概述2、D型触发器3、二分频计数器4、MOD-4 计数器5、模“m”计数器5.1 模5计数器5.2 模 10 计数器6、总结MOD 计数器是级联计数器电路,在复位之前计数到设定的模数值。 1、概述 计数器的工作是通过每个时钟脉冲将计数器的内容前进一个计数来进…

中值滤波结合快速排序算法优化传感器数据预处理

一、算法核心逻辑 目标&#xff1a;在嵌入式系统中&#xff0c;通过快速排序的 “部分排序” 特性&#xff0c;优化中值滤波的计算效率。适用场景&#xff1a;实时传感器数据处理&#xff08;如红外、超声波、加速度计等&#xff09;&#xff0c;窗口大小 N5&#xff08;可根据…

使用逻辑分析仪测量RS485的通讯方法

1. 硬件连接 连接参考地&#xff1a;逻辑分析仪的参考地需要连接到被测设备RS-485收发器的参考地。信号线连接&#xff1a;有以下几种接线方式&#xff1a; 单线连接&#xff1a;将逻辑分析仪的一个信号通道连接到RS-485总线的A端。双线连接&#xff1a;用逻辑分析仪两个信号通…

【六祎 - Note】SQL备忘录;DDL,DML,DQL,DCL

SQL备忘录 from to : 点击访问源地址

9、HTTP/2与HTTP/1.1的区别?【高频】

二进制协议&#xff1a; HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文&#xff0c;而是全面采用了二进制格式&#xff0c;报文头部和数据体都是二进制&#xff0c;并且统称为帧&#xff08;frame&#xff09;&#xff1a;头信息帧&#xff08;Headers Frame&#xff09;和数据…

使用write函数

使用open命令打开文件后&#xff0c;要往里面写入数据&#xff0c;使用write命令&#xff0c;把buf中count字节的数据写入fd中 关键是&#xff0c;写文件的时候要在这个文件的哪一个位置去写 假如写得时候&#xff0c;文件为空&#xff0c;指针指向最开始的位置&#xff0c;执…

001 Kafka入门及安装

Kafka入门及安装 文章目录 Kafka入门及安装1.介绍Kafka的基本概念和核心组件 2.安装1.docker快速安装zookeeper安装kafka安装 添加topic删除topickafka-ui安装 2.Docker安装&#xff08;SASL/PLAIN认证配置-用户名密码&#xff09; 来源参考的deepseek&#xff0c;如有侵权联系…