本文由 简悦 SimpRead 转码, 原文地址 http://www.mybatis.cn/archives/762.html
计算机有两大基本的功能:计算和存储。在存储方面,缓存的设计和实现也是一门学问。这门学问里面包含什么门道呢?不妨研究一下 MyBatis 缓存类 PerpetualCache,一定会大有收获的。
在 MyBatis 里面,存在一个 PerpetualCache,它是一级缓存、二级缓存的最基本实现,但 PerpetualCache 只不过包装了一下 HashMap。Perpetual 是 “永久、不间断” 之意,以 PerpetualCache 为根本,在 cache.decorators 包里面有多种缓存的代理,实现了各种清除策略。
1、PerpetualCache 名字的含义
Perpetual 是 “永久、不间断” 之意,为什么这么命名呢?稍加联系,便能明白。缓存的设计有两个重点问题:如何存储数据和采用何种清除策略。存储的话,用哈希表即可完美解决。对于清除策略而言,往往有多种选择。MyBatis 作者 Clinton Begin 选择 Perpetual 来命名缓存,暗示这是一个最底层的缓存,数据一旦存储进来,永不清除,如果实现清除策略,请把 Perpetual 包装一下。在 cache.decorators 包里面有多种缓存,它们内部串联的主线就是按照 “不同的清除策略” 来贯穿的。
2、PerpetualCache 的实现原理:
PerpetualCache 仅仅是包装了 HashMap,代码如下所示:
1 | public class PerpetualCache implements Cache |
PerpetualCache 的读取数据,也是通过内部的 HashMap 来实现的,代码如下所示:
1 | @Override |
3、Key 的设计:CacheKey
在 PerpetualCache 内部使用的 Java 自带的 HashMap:
Map<Object, Object> cache = new HashMap<Object, Object>();
但是,HashMap 的 Key 设计略显单薄,无法适应复杂的缓存场景,需要进行自定义设计。MyBatis 实现了 CacheKey 类,其功能非常的强大。
1 | public class CacheKey implements Cloneable, Serializable |
代码分析如下所示:
(1)hashcode,用于表示 CacheKey 的哈希码
(2)checksum,总和校验,当出现复合 key 的时候,分布计算每个 key 的哈希码,然后求总和
(3)count,当出现复合 key 的时候,计算 key 的总个数
(4)updateList,当出现复合 key 的时候,保存每个 key
CacheKey 这个类设计的非常好,个人推荐感兴趣的人可以仔细读一读其源码。其初始化的过程如下所示:
1 | public CacheKey(Object[] objects) |





