Skip to content

MyBatis缓存机制 ​

深入理解MyBatis的缓存机制,掌握一级缓存和二级缓存的实现原理,理解缓存更新、缓存优化等核心功能。

📋 缓存机制概览 ​

MyBatis提供了两级缓存机制,提高查询性能。

🎯 一、一级缓存 ​

1.1 一级缓存实现 ​

BaseExecutor:

java
protected abstract class BaseExecutor implements Executor {
    protected PerpetualCache localCache;
    
    @Override
    public <E> List<E> query(MappedStatement ms, Object parameter, 
            RowBounds rowBounds, ResultHandler resultHandler) 
            throws SQLException {
        BoundSql boundSql = ms.getBoundSql(parameter);
        CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);
        return query(ms, parameter, rowBounds, resultHandler, key, boundSql);
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public <E> List<E> query(MappedStatement ms, Object parameter, 
            RowBounds rowBounds, ResultHandler resultHandler, 
            CacheKey key, BoundSql boundSql) throws SQLException {
        List<E> list;
        try {
            queryStack++;
            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--;
        }
        if (queryStack == 0) {
            for (DeferredLoad deferredLoad : deferredLoads) {
                deferredLoad.load();
            }
            deferredLoads.clear();
            if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
                clearLocalCache();
            }
        }
        return list;
    }
}

1.2 缓存作用域 ​

LocalCacheScope:

  • SESSION:SqlSession级别(默认)
  • STATEMENT:语句级别

🎯 二、二级缓存 ​

2.1 二级缓存实现 ​

CachingExecutor:

java
public class CachingExecutor implements Executor {
    private final Executor delegate;
    private final TransactionalCacheManager tcm = 
            new TransactionalCacheManager();
    
    @Override
    public <E> List<E> query(MappedStatement ms, Object parameterObject, 
            RowBounds rowBounds, ResultHandler resultHandler, 
            CacheKey key, BoundSql boundSql) throws SQLException {
        Cache cache = ms.getCache();
        if (cache != null) {
            flushCacheIfRequired(ms);
            if (ms.isUseCache() && resultHandler == null) {
                ensureNoOutParams(ms, boundSql);
                @SuppressWarnings("unchecked")
                List<E> list = (List<E>) tcm.getObject(cache, key);
                if (list == null) {
                    list = delegate.query(ms, parameterObject, rowBounds, 
                            resultHandler, key, boundSql);
                    tcm.putObject(cache, key, list);
                }
                return list;
            }
        }
        return delegate.query(ms, parameterObject, rowBounds, resultHandler, 
                key, boundSql);
    }
}

2.2 缓存更新 ​

缓存更新时机:

  • INSERT:清空相关缓存
  • UPDATE:清空相关缓存
  • DELETE:清空相关缓存

📖 学习资源 ​

视频教程 ​

书籍推荐 ​

  • 《MyBatis技术内幕》 - 徐郡明

网站资源 ​

✅ 学习检查清单 ​

  • [ ] 已理解一级缓存实现
  • [ ] 已理解二级缓存实现
  • [ ] 已理解缓存更新机制
  • [ ] 已理解缓存优化
  • [ ] 已总结核心知识点

上一章节:MyBatis结果集处理
下一章节:Tomcat请求处理
返回目录:Mybatis和Tomcat源码深度解析