第五章-Mybatis源码解析-执行流程(二)

5.1.1.2 CachingExecutor执行器

接着进到 CachingExecutor.query 方法

java 复制代码
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
    // 首先也要拿到BoundSql,这个直接看章节`5.1.1.1-1`和`5.1.1.1-2`
    BoundSql boundSql = ms.getBoundSql(parameterObject);
    // 这一步参考章节`5.1.1.1-3`
    CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
    // 查询,继续往下看
    return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}

public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
    throws SQLException {
    // 取出mapper对应的二级缓存的实现对象,二级缓存是全局性的,一级缓存是会话级/请求级
    Cache cache = ms.getCache();
    if (cache != null) {
        // 如果设置了该语句  flushCache="true" ,那么执行前要清空缓存先
        flushCacheIfRequired(ms);
        // 如果该语句设置了  useCache="true" ,就是要走缓存的意思,同时 resultHandler 为空,也就是说处理结果交给mybatis,必须两个条件都符合
        if (ms.isUseCache() && resultHandler == null) {
            ensureNoOutParams(ms, boundSql);
            @SuppressWarnings("unchecked")
            // 先从缓存中取值(注意:没有commit的结果不会存到缓存中,这一点也是与一级缓存不同的地方)
            List<E> list = (List<E>) tcm.getObject(cache, key);
            if (list == null) {
                // 缓存中没值,就执行查询,参考章节`5.1.1.1-4`
                list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
                // 查到了值,放二级缓存中
                tcm.putObject(cache, key, list); // issue #578 and #116
            }
            return list;
        }
    }
    // 参考章节`5.1.1.1-4`
    return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}

5.1.2 insert

Mybatis默认提供的SqlSession实现类是DefaultSqlSession,那直接进入这个类

java 复制代码
/**
statement:对应mapper配置中的语句id
parameter:传参
*/
public int insert(String statement, Object parameter) {
    // 调用的是update方法
    return update(statement, parameter);
}

public int update(String statement, Object parameter) {
    try {
        dirty = true;
        // 取出 MappedStatement 对象
        MappedStatement ms = configuration.getMappedStatement(statement);
        // 为啥insert 是用的执行器的update方法呢,因为 Executor 接口中就没有定义 insert 方法,所以cud,都是走的update方法,r 则走的是 query方法。
        return executor.update(ms, wrapCollection(parameter));
    } catch (Exception e) {
        throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);
    } finally {
        ErrorContext.instance().reset();
    }
}

executor.update 方法,这里指的是CachingExecutor类的update方法

java 复制代码
public int update(MappedStatement ms, Object parameterObject) throws SQLException {
    // 有必要(该语句  flushCache="true" )则清空缓存
    flushCacheIfRequired(ms);
    // 这一步走到BaseExecutor.update方法
    return delegate.update(ms, parameterObject);
}

BaseExecutor类的update方法

java 复制代码
public int update(MappedStatement ms, Object parameter) throws SQLException {
    ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());
    if (closed) { // 检查执行器的状态
        throw new ExecutorException("Executor was closed.");
    }
    // 先清空一级缓存
    clearLocalCache();
    // 子类实现 doUpdate 方法,这里是指 SimpleExecutor 子类
    return doUpdate(ms, parameter);
}

SimpleExecutor类的doUpdate方法

java 复制代码
public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
    Statement stmt = null;
    try {
        // 拿到 configuration 对象
        Configuration configuration = ms.getConfiguration();
         // 拿到 StatementHandler,这个对象就是真正跟jdbc打交道的,封装了jdbc对数据的操作,详情解析看章节`第六章`,以下执行流程都放在`第六章`讲解
        StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
        // 预处理操作
        stmt = prepareStatement(handler, ms.getStatementLog());
        // 执行操作
        return handler.update(stmt);
    } finally {
        closeStatement(stmt);
    }
}
相关推荐
梅小西爱学习3 分钟前
线上CPU飙到100%?别慌,这3个工具比top快10倍!
java·后端·cpu
没有bug.的程序员9 分钟前
金融支付分布式架构实战:从理论到生产级实现
java·分布式·微服务·金融·架构·分布式调度系统
00后程序员张9 分钟前
Jenkins Pipeline post指令详解
java·开发语言
程序员阿达16 分钟前
开题报告之基于SpringBoot框架的路面故障信息上报系统设计与实现
java·spring boot·后端
哞哞不熬夜27 分钟前
JavaEE--SpringIoC
java·开发语言·spring boot·spring·java-ee·maven
滑水滑成滑头29 分钟前
**点云处理:发散创新,探索前沿技术**随着科技的飞速发展,点云处理技术在计算机视觉、自动驾驶、虚拟现实等领域的应用愈发广
java·python·科技·计算机视觉·自动驾驶
千里马-horse37 分钟前
fastddsgen.jar 简介
java·jar·fast dds·fastddsgen
TT哇38 分钟前
【Maven】Maven设置国内源
java·maven
dyj0951 小时前
【Devops-Jenkins自动将Java Maven工程编译成jar、并打成Docker镜像,并上传Harbor】
java·jenkins·devops
gordon~91 小时前
Spring 的bean是安全的吗
java·安全·spring·bean