Java Mybatis - 一级缓存
介绍
默认情况下,Mybatis 只开启一级缓存,一级缓存只是相对于同一个 SqlSession 而言。所以在参数和 SQL 完全一样的情况下,我们使用同一个 SqlSession 对象连续调用同一个 Mapper 方法,往往只执行一次SQL,不会再次发送 SQL 到数据库。
源码
DefaultSqlSession selectList 方法
public class DefaultSqlSession implements SqlSession {
public List selectList(String statement, Object parameter, RowBounds rowBounds) {
MappedStatement ms = configuration.getMappedStatement(statement);
return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
}
}
BaseExecutor query 方法
public abstract class BaseExecutor implements Executor {
protected PerpetualCache localCache;
public List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler){
BoundSql boundSql = ms.getBoundSql(parameter);
CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);
return query(ms, parameter, rowBounds, resultHandler, key, boundSql);
}
public List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql){
List list;
// 一级缓存中取数据
list = resultHandler == null ? (List) localCache.getObject(key) : null;
if (list != null) {
handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
} else {
list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
}
return list;
}
}
PerpetualCache getObject 方法
public class PerpetualCache implements Cache {
//一级缓存的本质就是一个 HashMap
private final Map