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()

                










