MyBatis 大家都知道有,一级缓存、二级缓存,不过很多人不知道具体的实现,和怎么扩展。
二级缓存,也可以称为 第三者缓存/外部缓存
代码如下:
// BaseExecutor@Overridepublic <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {// 生产 BoundSql,里面包含sql模板和需要的参数BoundSql boundSql = ms.getBoundSql(parameter);// 生产cacheKey,用于二级缓存CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);return query(ms, parameter, rowBounds, resultHandler, key, boundSql);}
说明:
BoundSql
里面就是 sql 模板和 sql 需要的参数 ,根据这个生产 CacheKey (这也是为什么,sql 完全一样,参数不一样的时候,不能命中缓存的原因)。
query
方法里面就会去检查缓存了,根据 CacheKey 。
// BaseExecutor@SuppressWarnings("unchecked")@Overridepublic <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {// 略...try {// 查询计数++queryStack++;// tip: localCache 是 PerpetualCache(永久缓存)list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;if (list != null) {handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);} else {// 查询数据库list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);}} finally {queryStack--;}// 略...return list;}
说明:
localCache.getObject
这里,根据我们生产的 CacheKey
获取对应的缓存,不存在就去 查询数据库 。完结~