第六章-Mybatis源码解析-StatementHandler语句处理和执行(二)

6.3 query查询处理

查询操作的时候,也会针对语句类型的不同,分别由 SimpleStatementHandler、PreparedStatementHandler、CallableStatementHandler (存储过程的,这里不展开讲解)各自实现

SimpleStatementHandler方式

public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
    String sql = boundSql.getSql(); // 拿到语句
    statement.execute(sql); // jdbc 方式的执行语句
    // 处理结果,留待`第七章`讲解
    return resultSetHandler.handleResultSets(statement);
}

PreparedStatementHandler方式

public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute(); // 执行语句
    // 处理结果,留待`第七章`讲解
    return resultSetHandler.handleResultSets(ps);
}

6.4 update更新处理

SimpleStatementHandler方式

public int update(Statement statement) throws SQLException {
    String sql = boundSql.getSql(); // 拿到sql
    // 参数
    Object parameterObject = boundSql.getParameterObject();
    // 章节`3.2.2.7 selectKey解析`中有描述
    KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
    int rows;
    // 接下来,都是jdbc的代码了
    if (keyGenerator instanceof Jdbc3KeyGenerator) {
        statement.execute(sql, Statement.RETURN_GENERATED_KEYS);
        rows = statement.getUpdateCount();
        keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
    } else if (keyGenerator instanceof SelectKeyGenerator) {
        statement.execute(sql);
        rows = statement.getUpdateCount();
        keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
    } else {
        statement.execute(sql);
        rows = statement.getUpdateCount();
    }
    return rows;
}

PreparedStatementHandler方式

 public int update(Statement statement) throws SQLException {
     PreparedStatement ps = (PreparedStatement) statement;
     ps.execute(); // jdbc 方式执行
     int rows = ps.getUpdateCount(); // 返回的更新行数
     // 参数
     Object parameterObject = boundSql.getParameterObject();
     // 章节`3.2.2.7 selectKey解析`中有描述,这里以 SelectKeyGenerator 举例
     KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
     // 设置处理后的 keyGenerator 的值
     keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
     return rows;
 }

SelectKeyGenerator.processAfter

这一步很简单,就不一行行代码解析了,这个方法的功能就是,在设置配置时各属性的值

 public void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
     if (!executeBefore) {
         processGeneratedKeys(executor, ms, parameter);
     }
 }

private void processGeneratedKeys(Executor executor, MappedStatement ms, Object parameter) {
    try {
        if (parameter != null && keyStatement != null && keyStatement.getKeyProperties() != null) {
            String[] keyProperties = keyStatement.getKeyProperties();
            final Configuration configuration = ms.getConfiguration();
            final MetaObject metaParam = configuration.newMetaObject(parameter);
            if (keyProperties != null) {
                // Do not close keyExecutor.
                // The transaction will be closed by parent executor.
                Executor keyExecutor = configuration.newExecutor(executor.getTransaction(), ExecutorType.SIMPLE);
                List<Object> values = keyExecutor.query(keyStatement, parameter, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
                if (values.size() == 0) {
                    throw new ExecutorException("SelectKey returned no data.");
                } else if (values.size() > 1) {
                    throw new ExecutorException("SelectKey returned more than one value.");
                } else {
                    MetaObject metaResult = configuration.newMetaObject(values.get(0));
                    if (keyProperties.length == 1) {
                        if (metaResult.hasGetter(keyProperties[0])) {
                            // 看这就行了,设置单个值
                            setValue(metaParam, keyProperties[0], metaResult.getValue(keyProperties[0]));
                        } else {
                            // no getter for the property - maybe just a single value object
                            // so try that
						  // 看这就行了,设置单个值
                            setValue(metaParam, keyProperties[0], values.get(0));
                        }
                    } else {
                        // 设置多个值
                        handleMultipleProperties(keyProperties, metaParam, metaResult);
                    }
                }
            }
        }
    } catch (ExecutorException e) {
        throw e;
    } catch (Exception e) {
        throw new ExecutorException("Error selecting key or setting result to parameter object. Cause: " + e, e);
    }
}
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多栖码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值