CallableStatementHandler实际就是使用CallableStatement来执行SQL语句,当然它执行的是存储过程。

源码如下:

/**
 * @author Clinton Begin
 */
/***/
public class CallableStatementHandler extends BaseStatementHandler {

  public CallableStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
    super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
  }

  public int update(Statement statement)
      throws SQLException {
	//用来调用存储过程,它提供了对输出和输入/输出参数的支持
    CallableStatement cs = (CallableStatement) statement;
    cs.execute();
    int rows = cs.getUpdateCount();
    Object parameterObject = boundSql.getParameterObject();
    KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
    keyGenerator.processAfter(executor, mappedStatement, cs, parameterObject);

    resultSetHandler.handleOutputParameters(cs);
    return rows;
  }

  public void batch(Statement statement)
      throws SQLException {
    CallableStatement cs = (CallableStatement) statement;
    cs.addBatch();
  }

  public <E> List<E> query(Statement statement, ResultHandler resultHandler)
      throws SQLException {
    CallableStatement cs = (CallableStatement) statement;
    cs.execute();
    List<E> resultList = resultSetHandler.<E>handleResultSets(cs);
    resultSetHandler.handleOutputParameters(cs);
    return resultList;
  }

  protected Statement instantiateStatement(Connection connection) throws SQLException {
    String sql = boundSql.getSql();
    if (mappedStatement.getResultSetType() != null) {
      return connection.prepareCall(sql, mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
    } else {
      return connection.prepareCall(sql);
    }
  }

  public void parameterize(Statement statement) throws SQLException {
	 //注册out参数
    registerOutputParameters((CallableStatement) statement);
    parameterHandler.setParameters((CallableStatement) statement);
  }

  private void registerOutputParameters(CallableStatement cs) throws SQLException {
    List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
    for (int i = 0, n = parameterMappings.size(); i < n; i++) {
      ParameterMapping parameterMapping = parameterMappings.get(i);
	  //处理存储过程的INOUT和OUT
      if (parameterMapping.getMode() == ParameterMode.OUT || parameterMapping.getMode() == ParameterMode.INOUT) {
        if (null == parameterMapping.getJdbcType()) {
          throw new ExecutorException("The JDBC Type must be specified for output parameter.  Parameter: " + parameterMapping.getProperty());
        } else {
          if (parameterMapping.getNumericScale() != null && (parameterMapping.getJdbcType() == JdbcType.NUMERIC || parameterMapping.getJdbcType() == JdbcType.DECIMAL)) {
            cs.registerOutParameter(i + 1, parameterMapping.getJdbcType().TYPE_CODE, parameterMapping.getNumericScale());
          } else {
            if (parameterMapping.getJdbcTypeName() == null) {
              cs.registerOutParameter(i + 1, parameterMapping.getJdbcType().TYPE_CODE);
            } else {
              cs.registerOutParameter(i + 1, parameterMapping.getJdbcType().TYPE_CODE, parameterMapping.getJdbcTypeName());
            }
          }
        }
      }
    }
  }

}

Mybatis源码之Statement处理器CallableStatementHandler(六)的更多相关文章

  1. Mybatis源码之Statement处理器StatementHandler(一)

    StatementHandler通过类名我们可以了解到它可能是Statement的处理器,它是一个接口,其实现类如下: BaseStatementHandler:一个抽象类,只是实现了一些不涉及具体操 ...

  2. Mybatis源码之Statement处理器RoutingStatementHandler(三)

    RoutingStatementHandler类似路由器,在其构造函数中会根据Mapper文件中设置的StatementType来选择使用SimpleStatementHandler.Prepared ...

  3. Mybatis源码之Statement处理器PreparedStatementHandler(五)

    PreparedStatementHandler就是调用PreparedStatement来执行SQL语句,这样在第一次执行sql语句时会进行预编译,在接下来执行相同的SQL语句时会提高数据库性能 源 ...

  4. Mybatis源码之Statement处理器SimpleStatementHandler(四)

    SimpleStatementHandler就是使用基本的Statement来执行query.batch.update等操作,其实现还是比较简单的,当然在执行过程中会涉及keyGenerator和Re ...

  5. Mybatis源码之Statement处理器BaseStatementHandler(二)

    BaseStatementHandler是一个抽象类,并没有实现和CURD相关的类,只是更多的设置了一些参数相关. 源码如下: /** * @author Clinton Begin */ publi ...

  6. MyBatis 源码分析——类型处理器

    官网上面讲到:无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型.那 ...

  7. Mybatis源码分析之存储过程调用

    这一篇博客我们学习一下Mybatis调用存储过程的使用和运行流程.首先我们先创建一个简单的存储过程 DELIMITER $ CREATE PROCEDURE mybatis.ges_user_coun ...

  8. Mybatis源码解析,一步一步从浅入深(六):映射代理类的获取

    在文章:Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们提到了两个问题: 1,为什么在以前的代码流程中从来没有addMapper,而这里却有getMapper? 2,UserDao ...

  9. MyBatis 源码分析 - SQL 的执行过程

    * 本文速览 本篇文章较为详细的介绍了 MyBatis 执行 SQL 的过程.该过程本身比较复杂,牵涉到的技术点比较多.包括但不限于 Mapper 接口代理类的生成.接口方法的解析.SQL 语句的解析 ...

随机推荐

  1. mybatis添加记录时返回主键id

    参考:mybatis添加记录时返回主键id 场景 有些时候我们在添加记录成功后希望能直接获取到该记录的主键id值,而不需要再执行一次查询操作.在使用mybatis作为ORM组件时,可以很方便地达到这个 ...

  2. ACM 排列2

    Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数.  Input每组数据占一行,代表四张卡片上的数字(0<=数字<=9 ...

  3. PHP 实例 - AJAX 实时搜索

    AJAX Live Search 在下面的实例中,我们将演示一个实时的搜索,在您键入数据的同时即可得到搜索结果. 实时的搜索与传统的搜索相比,具有很多优势: 当键入数据时,就会显示出匹配的结果 当继续 ...

  4. Python3 条件控制

    if 语句 Python中if语句的一般形式如下所示: if condition_1: statement_block_1 elif condition_2: statement_block_2 el ...

  5. TensorFlow入门和示例分析

    本文以TensorFlow源码中自带的手写数字识别Example为例,引出TensorFlow中的几个主要概念.并结合Example源码一步步分析该模型的实现过程. 一.什么是TensorFlow 在 ...

  6. [LaTeX] box algorithm adjustbox subfigures, textwidth

    algorithm \begin{figure}[!t] \vspace*{\dimexpr\fboxsep+\fboxrule} \fbox{% \parbox{\dimexpr\linewidth ...

  7. Common-used commands in Docker

    1. Start running a image in background mode docker run -it -d <image>:<tag> e.g. docker ...

  8. 计算机网络之套接字SOCKET

    当某个应用进程启动系统调用时,控制权就从应用进程传递给了系统调用接口. 此接口再将控制权传递给计算机的操作系统.操作系统将此调用转给某个内部过程,并执行所请求的操作. 内部过程一旦执行完毕,控制权就又 ...

  9. 从Stage角度看cassandra write

    声明 文章发布于CSDN cassandra concurrent 具体实现 cassandra并发技术文中介绍了java的concurrent实现,这里介绍cassandra如何基于java实现ca ...

  10. Cocos2D-ObjC:在RPG游戏中混合Swift代码

    我之前写过一个RPG游戏<<熊猫之魂 SoulOfPanda>> 编译器使用的是SpriteBuilder,很好很强大!全部代码都由Objc完成,现在想尝试一下在其中混入Swi ...