BatchExecutor:顾名思义就是进行批量操作,通过批量操作来提高性能

public class BatchExecutor extends BaseExecutor {

  public static final int BATCH_UPDATE_RETURN_VALUE = Integer.MIN_VALUE + 1002;

  /* Statement链表**/
  private final List<Statement> statementList = new ArrayList<Statement>();

  /* batch结果链表**/
  private final List<BatchResult> batchResultList = new ArrayList<BatchResult>();
  private String currentSql;
  private MappedStatement currentStatement;

  public BatchExecutor(Configuration configuration, Transaction transaction) {
    super(configuration, transaction);
  }

  @Override
  public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLException {
	//获得配置信息
    final Configuration configuration = ms.getConfiguration();
	//获得StatementHandler
    final StatementHandler handler = configuration.newStatementHandler(this, ms, parameterObject, RowBounds.DEFAULT, null, null);
    final BoundSql boundSql = handler.getBoundSql();
	//获得Sql语句
    final String sql = boundSql.getSql();
    final Statement stmt;
	//如果sql语句等于当前sql MappedStatement 等于当前Map碰到Statement
    if (sql.equals(currentSql) && ms.equals(currentStatement)) {

      int last = statementList.size() - 1;
	  //获得最后一个
      stmt = statementList.get(last);
	  handler.parameterize(stmt);//fix Issues 322
	  //有相同的MappedStatement和参数
      BatchResult batchResult = batchResultList.get(last);
      batchResult.addParameterObject(parameterObject);
    } else {
	  //如果不存在就创建一个批处理操作
      Connection connection = getConnection(ms.getStatementLog());
      stmt = handler.prepare(connection);
      handler.parameterize(stmt);    //fix Issues 322
      currentSql = sql;
      currentStatement = ms;
	  //添加批量处理操作
      statementList.add(stmt);
      batchResultList.add(new BatchResult(ms, sql, parameterObject));
    }
  // handler.parameterize(stmt);
    //最终是调用jdbc的批处理操作
    handler.batch(stmt);
    return BATCH_UPDATE_RETURN_VALUE;
  }

  @Override
  public <E> List<E> doQuery(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
      throws SQLException {
    Statement stmt = null;
    try {
      flushStatements();
	  //获得配置信息
      Configuration configuration = ms.getConfiguration();
	  //获得StatementHandler
      StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameterObject, rowBounds, resultHandler, boundSql);
	  //获得连接
      Connection connection = getConnection(ms.getStatementLog());
      stmt = handler.prepare(connection);
	  //获得Statement
      handler.parameterize(stmt);
      return handler.<E>query(stmt, resultHandler);
    } finally {
      closeStatement(stmt);
    }
  }

  /* 刷新Statement,记录执行次数*/
  @Override
  public List<BatchResult> doFlushStatements(boolean isRollback) throws SQLException {
    try {
      List<BatchResult> results = new ArrayList<BatchResult>();
      if (isRollback) {
        return Collections.emptyList();
      }
	  //如果进行了批量处理
      for (int i = 0, n = statementList.size(); i < n; i++) {
        Statement stmt = statementList.get(i);
        BatchResult batchResult = batchResultList.get(i);
        try {
		  //记录批量处理执行操作的条数
          batchResult.setUpdateCounts(stmt.executeBatch());
          MappedStatement ms = batchResult.getMappedStatement();
		  //参数对象集合
          List<Object> parameterObjects = batchResult.getParameterObjects();
		  //生成key
          KeyGenerator keyGenerator = ms.getKeyGenerator();
          if (Jdbc3KeyGenerator.class.equals(keyGenerator.getClass())) {
            Jdbc3KeyGenerator jdbc3KeyGenerator = (Jdbc3KeyGenerator) keyGenerator;
            jdbc3KeyGenerator.processBatch(ms, stmt, parameterObjects);
          } else if (!NoKeyGenerator.class.equals(keyGenerator.getClass())) { //issue #141
            for (Object parameter : parameterObjects) {
              keyGenerator.processAfter(this, ms, stmt, parameter);
            }
          }
        } catch (BatchUpdateException e) {
          StringBuilder message = new StringBuilder();
          message.append(batchResult.getMappedStatement().getId())
              .append(" (batch index #")
              .append(i + 1)
              .append(")")
              .append(" failed.");
          if (i > 0) {
            message.append(" ")
                .append(i)
                .append(" prior sub executor(s) completed successfully, but will be rolled back.");
          }
          throw new BatchExecutorException(message.toString(), e, results, batchResult);
        }
		//记录操作
        results.add(batchResult);
      }
      return results;
    } finally {
      for (Statement stmt : statementList) {
        closeStatement(stmt);
      }
      currentSql = null;
      statementList.clear();
      batchResultList.clear();
    }
  }

}

Mybatis执行BatchExecutor(四)的更多相关文章

  1. Mybatis执行CachingExecutor(六)

    前面几篇博客我们介绍了Excutor及抽象类BaseExecutor和实现类SimpleExecutor.BatchExecutor和ReuseExecutor: 博客列表: Mybatis执行Exe ...

  2. MyBatis学习 之 四、MyBatis配置文件

    目录(?)[-] 四MyBatis主配置文件 properties属性 settings设置 typeAliases类型别名 typeHandlers类型句柄 ObjectFactory对象工厂 pl ...

  3. 【转】MyBatis学习总结(四)——解决字段名与实体类属性名不相同的冲突

    [转]MyBatis学习总结(四)——解决字段名与实体类属性名不相同的冲突 在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这种情况下的如何解决字段名与实体 ...

  4. Mybatis动态SQL简单了解 Mybatis简介(四)

    动态SQL概况 MyBatis 的强大特性之一便是它的动态 SQL 在Java开发中经常遇到条件判断,比如: if(x>0){ //执行一些逻辑........ }   Mybatis应用中,S ...

  5. Mybatis执行流程浅析(附深度文章推荐&面试题集锦)

    首先推荐一个简单的Mybatis原理视频教程,可以作为入门教程进行学习:点我 (该教程讲解的是如何手写简易版Mybatis) 执行流程的理解 理解Mybatis的简单流程后自己手写一个,可以解决百分之 ...

  6. 精尽MyBatis源码分析 - MyBatis初始化(四)之 SQL 初始化(下)

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  7. mybatis执行批量更新update

    Mybatis的批量插入这里有http://ljhzzyx.blog.163.com/blog/static/38380312201353536375/.目前想批量更新,如果update的值是相同的话 ...

  8. acid数据库事务正确执行的四个基本要素的缩写编辑本义项

    ACID,指数据库事务正确执行的四个基本要素的缩写.包含:原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持久性(Durability).一个支持事务(T ...

  9. ACID:数据库事务正确执行的四个基本要素

    ACID,指数据库事务正确执行的四个基本要素的缩写.包含:原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持久性(Durability).一个支持事务(T ...

随机推荐

  1. 阿里2019实习内推,五轮技术面+一轮HR面,Java岗面经

    在牛客网上获取到很多知识和信息,现在反馈一波,希望能对广大找实习的同学有所帮助. 个人情况:EE方向渣硕,二月末内推了阿里集团某部门Java岗,约三周完成了所有面试. 面经如下: 一面 (简历评估): ...

  2. python四则运算

    源代码已上传至Github,https://github.com/chaigee/arithmetic,中的python_ari.py文件 题目: (1)能自动生成小学四则运算题目,并且不能出现负数: ...

  3. JavaScript判断不同平台

    function getPlatformType() { let UA = navigator.userAgent; if(/MicroMessenger/i.test(UA)){ return 'w ...

  4. Node.js ZLIB

    Zlib 稳定性: 3 - 文档 可以通过以下方式访问这个模块: var zlib = require('zlib'); 这个模块提供了对 Gzip/Gunzip, Deflate/Inflate, ...

  5. Bootstrap3 代码-变量

    通过 <var> 标签标记变量. y = mx + b <var>y</var> = <var>m</var><var>x< ...

  6. Mybatis源码分析之参数映射及处理ParameterHandler

    ParameterHandler是用来设置参数规则的,当StatementHandler调用prepare方法之后,接下来就是调用它来进行设置参数. ParameterHandler接口: publi ...

  7. 修改CUSTOM.PLL文件调用客户化FORM&修改标准FORM

    修改custom.pll文件里 的过程event:参考例子如下,修改好后上传至$AU_TOP/resource 运行编译frmcmp_batch CUSTOM apps/apps module_typ ...

  8. 如何将dtb反编译成dts

    点击打开链接 由于device tree会将一个node的信息分布在各个文件里,查看起来很不方便,比如如下例子,ldb在三个文件中都有配置: imx6qdl-sabresd.dtsi: [plain] ...

  9. 看见的力量 – (I) 解题的思维

    本文转自台湾李智桦老师的博客,原文地址 这篇文章:已经梗了我三个多星期了.这期间飞了二次大陆做演讲.往返几个大城市做教授敏捷开发运用在精实创业的课程.教材内容都是简体的,它们始终没有机会在国内用上,心 ...

  10. 关于MT8127中sdk的编译出错问题

    今天在看MTK提供的SDK编译文档,按照步骤做,结果出错了,文档如下: 2- Building an SDK for MacOS and Linux ------------------------- ...