阅读 87

mybatis

一, myBatis一级缓存


解释:

1、什么缓存:
缓存就是数据的临时存储区,本质上来说是牺牲空间换取时间.例如cpu高速缓冲区,通过将数据暂存在高速缓冲区,避免了重复数据进行计算时,反复从内存中读取数据.


2、什么是myBatis一级缓存:当使用sqlSession从数据库查询数据时,mybatis会将查询到的数据暂存到内存中,当再次执行到相同的查询语句时,就可以直接从内存中获取到结果,而不需要再次获取数据库连接,从磁盘中获取.
需要注意的是,一级缓存的生命周期是在SqlSession中,也就是说,两个SqlSession对象之间是不会共享它们的一级缓存数据的.


上图的执行过程:

  1. 查询id为1的用户信息,从数据库获取数据.

  2. 将获取到的数据写入到一级缓存cache.

  3. 再次查询id为1的用户信息.

  4. 直接从一级缓存获取结果,不再查询数据库.

3、一级缓存什么时候会刷新:

  1. sqlSession去执行commit操作(插入,更新,删除),则会清空SqlSession中的一级缓存.

  2. SqlSession主动调用了clearCache()方法.

  3. 会话结束或者主动调用SqlSession.close()方法关闭会话.

4、一级缓存刷新:

关键方法:org.apache.ibatis.cache.impl.PerpetualCache#clear


可以发现cache是一个HashMap,因此刷新缓存也就是清空map.(cache.clear等价于map.clear)

5、myBatis是怎么判断两次查询是一致的:

上面提到当sqlSession再次查询id为1的用户信息时,会直接从一级缓存中获取数据,不会查询数据库.

那么myBatis到底时怎么保证两次相同的查询获取到同一份缓存呢.

现在我们知道cache是一个键值对结构的map.那么我们只能做到相同查询构建的key是相同的,那么是不是就可以保证不同查询语句之间不会互相干扰.

mybatis创建cacheKey的方法:
org.apache.ibatis.executor.BaseExecutor#createCacheKey

 @Override
    public CacheKey createCacheKey(...) {
        if (closed) {
            throw new ExecutorException("Executor was closed.");
        }
        // 创建 CacheKey 对象
        CacheKey cacheKey = new CacheKey();
        // statementId
        cacheKey.update(ms.getId());
        // 每页条数
        cacheKey.update(rowBounds.getOffset());
        // 页码
        cacheKey.update(rowBounds.getLimit());
        // 执行的sql
        cacheKey.update(boundSql.getSql());
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        TypeHandlerRegistry typeHandlerRegistry = ms.getConfiguration().getTypeHandlerRegistry();
        // 入参.
        for (ParameterMapping parameterMapping : parameterMappings) {
                ......
                cacheKey.update(value);
            }
        }
        // 环境id
        if (configuration.getEnvironment() != null) {
            // issue #176
            cacheKey.update(configuration.getEnvironment().getId());
        }
        return cacheKey;
    }

创建缓存key用到的参数:statementId,页码,分页条数,执行的sql,sql对应的入参,环境id.
通过这些条件就可以构成这样一个描述:执行开发环境StudyMapper.xml文件中id是findByCon的select user from user WHERE name=张三 LIMIT 1 ,10的查询语句.
通过这些条件可以很精确的定位到相同查询.
只要是环境,入参,分页条件等条件变化,cache.get(key)都不会再获取到之前缓存的值.



作者:xialu
链接:https://www.jianshu.com/p/ab4b15320470


文章分类
后端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐