mybatis源码-一级缓存

  作者:记性不好的阁主


流程图:




1、进入query方法





queryStack嵌套查询使用到的层级


@Override
public Object getObject(Object key) {
return cache.get(key);
}


private final Map<Object, Object> cache = new HashMap<>();


可以看到一级缓存底层就是一个hashmap作为缓存


缓存的key定义:




由6个部分组成:

1、statementId

2、分页条件:Integer的最小值0

3、分页条件:Interget的最大值2147483647

4、sql语句

5、参数

6、环境变量


第一次查询,缓存为null,那么就走doQuery查询数据库并填充缓存








第二次查询,直接获取缓存中的数据






验证上一节刷新缓存场景:mybatis源码-一级缓存命中的场景


1、update后会清空缓存


@Override
public int update(MappedStatement ms, Object parameter) throws SQLException {
ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());
if (closed) {
throw new ExecutorException("Executor was closed.");
}
clearLocalCache();
return doUpdate(ms, parameter);
}


2、配置flushCache=true会清空缓存


@Override
public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
if (closed) {
throw new ExecutorException("Executor was closed.");
}
if (queryStack == 0 && ms.isFlushCacheRequired()) {
clearLocalCache();
}
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();
}
// issue #601
deferredLoads.clear();
if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
// issue #482
clearLocalCache();
}
}
return list;
}



if (queryStack == 0 && ms.isFlushCacheRequired()) {
clearLocalCache();
}


这段代码表示:如果查询是第一次(不是子查询),并且配置了flushCache=true,那么清空缓存


3、配置localCacheScope=STATEMENT会清空缓存


if (queryStack == 0) {
for (DeferredLoad deferredLoad : deferredLoads) {
deferredLoad.load();
}
// issue #601
deferredLoads.clear();
if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
// issue #482
clearLocalCache();
}
}



这段代码表示:如果查询是第一次(不是子查询),并且配置了localCacheScope=STATEMENT,那么清空缓存


4、commit、rollback操作会清空缓存


@Override
public void commit(boolean required) throws SQLException {
if (closed) {
throw new ExecutorException("Cannot commit, transaction is already closed");
}
clearLocalCache();
flushStatements();
if (required) {
transaction.commit();
}
}

@Override
public void rollback(boolean required) throws SQLException {
if (!closed) {
try {
clearLocalCache();
flushStatements(true);
} finally {
if (required) {
transaction.rollback();
}
}
}
}



相关推荐

评论 抢沙发

表情

分类选择