mybatis 一级缓存源码分析
原创
©著作权归作者所有:来自51CTO博客作者_温柔一刀的原创作品,请联系作者获取转载授权,否则将追究法律责任
mybatis 一级缓存源码分析
- 使用场景
- 源码分析
- 清除缓存调用的情况
- 调用update
- 配置flushCache
- 作用域设置为STATEMENT
- 执行commit
- 执行rollback
- sqlSession 调用clearCache()
使用场景
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
/**
*一级缓存命中条件:
* 1.sql 和参数必须相同
* 2.必须是相同的statementId
* 3.sqlSession必须相同(会话级别的缓存)
* 4.RowBounds 返回行范围必须相同
*/
ActivityMapper mapper = sqlSession.getMapper(ActivityMapper.class);
ActivityEntity activity = mapper.getActivity(1);
//SqlSession sqlSession1 = sqlSessionFactory.openSession();
//ActivityMapper mapper1 = sqlSession1.getMapper(ActivityMapper.class);
/**
* 满足上面四个条件的前提条件下如何将缓存清除
* 1.sqlSession.clearCache();
* 2.未调用flushCache=true的查询
* 3。未执行update
*4。 缓存作用域不是STATEMENT——》将缓存作用域变小了,这种在子查询,嵌套查询中可以起作用
*/
sqlSession.clearCache();
ActivityEntity activity1 = mapper.getActivity(1);
System.out.println(activity==activity1);
}
源码分析
从上图可以看出来核心代码在query方法中,下面从query方法分析
org.apache.ibatis.executor.BaseExecutor#query
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--;
}
以上6种数据组成了缓存key
org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
List<E> list;
localCache.putObject(key, EXECUTION_PLACEHOLDER);
try {
//具体的Executor调用doQuery方法,查询数据库
list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
} finally {
localCache.removeObject(key);
}
//填充到缓存中
localCache.putObject(key, list);
if (ms.getStatementType() == StatementType.CALLABLE) {
localOutputParameterCache.putObject(key, parameter);
}
return list;
清除缓存调用的情况
调用update
配置flushCache
作用域设置为STATEMENT
执行commit
执行rollback
sqlSession 调用clearCache()