zoukankan      html  css  js  c++  java
  • mybatis的一级缓存

    1、mybatis缓存使用场景

    2、mybatis一级缓存命中场景

     当mybatis执行相关右边的操作时,均会执行clearCache()方法,清空对应缓存。

    一级缓存的作用域默认是sqlsession,也就是同一个会话。但是也可以设置为statement级别缓存,此时级别变小了。此时只有同一个statement的子查询才会命中缓存。

    只有满足左边条件才能命中缓存。

    一级缓存的key值,总共有6个值,0是statementid,1、2是分页条件,3是sql,4是参数,5是环境变量和命中场景中的参数一一对应。

    3、mybatis中缓存执行过程

    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;//resulthandle不为空表示自定义了结果集处理函数,此时就不需要走缓存了,因为你要自定义处理缓存
          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();//判断缓存作用域,如果是statment则直接删除缓存
          }
        }
        return list;
      }

    3.spring继承mybatis时,一级缓存失效?

    因为spring默认每一个查询都是一个事务,一个事务对应一个sqlsession会话,此时不在一个会话,当然不能命中。

    只需要在查询中加上事务,就可以解决。

    spring获取会话的数据结构。

    private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
        List<E> list;
        localCache.putObject(key, EXECUTION_PLACEHOLDER);//占位符,嵌套查询使用,防止死循环
        try {
          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;//返回结果
      }
  • 相关阅读:
    NSURLRequest的缓存策略
    React-Native安装使用
    iOS开发--XMPPFramework--环境的配置(一)
    iOS9 HTTP 网络访问问题
    数据交换的三种方法
    iOS项目--古典音乐浏览
    iOS学习笔记33
    iOS bug 日志 -frame 和 bounds的区别
    iOS学习笔记32
    iOS项目 画图小程序
  • 原文地址:https://www.cnblogs.com/sunanli/p/13586772.html
Copyright © 2011-2022 走看看