BatchExecutor是实现批处理操作,会将根据相同操作通过判断sql语句和MappedStatement来将执行放到List中,来执行批处理操作。

  1. /**
  2. * @author Jeff Butler
  3. */
  4. public class BatchExecutor extends BaseExecutor {
  5.  
  6. public static final int BATCH_UPDATE_RETURN_VALUE = Integer.MIN_VALUE + 1002;
  7.  
  8. /* Statement链表**/
  9. private final List<Statement> statementList = new ArrayList<Statement>();
  10.  
  11. /* batch结果链表**/
  12. private final List<BatchResult> batchResultList = new ArrayList<BatchResult>();
  13. private String currentSql;
  14. private MappedStatement currentStatement;
  15.  
  16. public BatchExecutor(Configuration configuration, Transaction transaction) {
  17. super(configuration, transaction);
  18. }
  19.  
  20. @Override
  21. public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLException {
  22. //获得配置信息
  23. final Configuration configuration = ms.getConfiguration();
  24. //获得StatementHandler
  25. final StatementHandler handler = configuration.newStatementHandler(this, ms, parameterObject, RowBounds.DEFAULT, null, null);
  26. final BoundSql boundSql = handler.getBoundSql();
  27. //获得Sql语句
  28. final String sql = boundSql.getSql();
  29. final Statement stmt;
  30. //如果sql语句等于当前sql MappedStatement 等于当前Map碰到Statement
  31. if (sql.equals(currentSql) && ms.equals(currentStatement)) {
  32.  
  33. int last = statementList.size() - 1;
  34. //获得最后一个
  35. stmt = statementList.get(last);
  36. handler.parameterize(stmt);//fix Issues 322
  37. //有相同的MappedStatement和参数
  38. BatchResult batchResult = batchResultList.get(last);
  39. batchResult.addParameterObject(parameterObject);
  40. } else {
  41. //如果不存在就创建一个批处理操作
  42. Connection connection = getConnection(ms.getStatementLog());
  43. stmt = handler.prepare(connection);
  44. handler.parameterize(stmt); //fix Issues 322
  45. currentSql = sql;
  46. currentStatement = ms;
  47. statementList.add(stmt);
  48. batchResultList.add(new BatchResult(ms, sql, parameterObject));
  49. }
  50. // handler.parameterize(stmt);
  51. //最终是调用jdbc的批处理操作
  52. handler.batch(stmt);
  53. return BATCH_UPDATE_RETURN_VALUE;
  54. }
  55.  
  56. @Override
  57. public <E> List<E> doQuery(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
  58. throws SQLException {
  59. Statement stmt = null;
  60. try {
  61. flushStatements();
  62. //获得配置信息
  63. Configuration configuration = ms.getConfiguration();
  64. //获得StatementHandler
  65. StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameterObject, rowBounds, resultHandler, boundSql);
  66. //获得连接
  67. Connection connection = getConnection(ms.getStatementLog());
  68. stmt = handler.prepare(connection);
  69. //获得Statement
  70. handler.parameterize(stmt);
  71. return handler.<E>query(stmt, resultHandler);
  72. } finally {
  73. closeStatement(stmt);
  74. }
  75. }
  76.  
  77. /* 暂时不知道它用来处理什么**/
  78. @Override
  79. public List<BatchResult> doFlushStatements(boolean isRollback) throws SQLException {
  80. try {
  81. List<BatchResult> results = new ArrayList<BatchResult>();
  82. if (isRollback) {
  83. return Collections.emptyList();
  84. }
  85. for (int i = 0, n = statementList.size(); i < n; i++) {
  86. Statement stmt = statementList.get(i);
  87. BatchResult batchResult = batchResultList.get(i);
  88. try {
  89. batchResult.setUpdateCounts(stmt.executeBatch());
  90. MappedStatement ms = batchResult.getMappedStatement();
  91. List<Object> parameterObjects = batchResult.getParameterObjects();
  92. KeyGenerator keyGenerator = ms.getKeyGenerator();
  93. if (Jdbc3KeyGenerator.class.equals(keyGenerator.getClass())) {
  94. Jdbc3KeyGenerator jdbc3KeyGenerator = (Jdbc3KeyGenerator) keyGenerator;
  95. jdbc3KeyGenerator.processBatch(ms, stmt, parameterObjects);
  96. } else if (!NoKeyGenerator.class.equals(keyGenerator.getClass())) { //issue #141
  97. for (Object parameter : parameterObjects) {
  98. keyGenerator.processAfter(this, ms, stmt, parameter);
  99. }
  100. }
  101. } catch (BatchUpdateException e) {
  102. StringBuilder message = new StringBuilder();
  103. message.append(batchResult.getMappedStatement().getId())
  104. .append(" (batch index #")
  105. .append(i + 1)
  106. .append(")")
  107. .append(" failed.");
  108. if (i > 0) {
  109. message.append(" ")
  110. .append(i)
  111. .append(" prior sub executor(s) completed successfully, but will be rolled back.");
  112. }
  113. throw new BatchExecutorException(message.toString(), e, results, batchResult);
  114. }
  115. results.add(batchResult);
  116. }
  117. return results;
  118. } finally {
  119. for (Statement stmt : statementList) {
  120. closeStatement(stmt);
  121. }
  122. currentSql = null;
  123. statementList.clear();
  124. batchResultList.clear();
  125. }
  126. }
  127.  
  128. }

myBatis源码之BatchExecutor的更多相关文章

  1. MyBatis源码分析(一)开篇

    源码学习的好处不用多说,Mybatis源码量少.逻辑简单,将写个系列文章来学习. SqlSession Mybatis的使用入口位于org.apache.ibatis.session包中的SqlSes ...

  2. Mybatis源码分析-SqlSessionTemplate

    承接Mybatis源码解析-MapperRegistry注册mapper接口,本文将在前文基础上讲解持久层的生成 SqlSessionFactory生成 在spring中,SqlSessionFact ...

  3. 【转】Mybatis源码解读-设计模式总结

    原文:http://www.crazyant.net/2022.html?jqbmtw=b90da1&gsjulo=kpzaa1 虽然我们都知道有26个设计模式,但是大多停留在概念层面,真实开 ...

  4. Mybatis源码分析之SqlSession和Excutor(二)

    通过上一篇文章的分析我们,我初步了解了它是如何创建sessionFactory的(地址:Mybatis源码分析之SqlSessionFactory(一)), 今天我们分析下Mybatis如何创建Sql ...

  5. Mybatis源码解读-设计模式总结

    虽然我们都知道有26个设计模式,但是大多停留在概念层面,真实开发中很少遇到,Mybatis源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,能够更深入的理解设计模式. Mybatis至少 ...

  6. MyBatis 源码篇-插件模块

    本章主要描述 MyBatis 插件模块的原理,从以下两点出发: MyBatis 是如何加载插件配置的? MyBatis 是如何实现用户使用自定义拦截器对 SQL 语句执行过程中的某一点进行拦截的? 示 ...

  7. Mybatis源码学习第六天(核心流程分析)之Executor分析

    今Executor这个类,Mybatis虽然表面是SqlSession做的增删改查,其实底层统一调用的是Executor这个接口 在这里贴一下Mybatis查询体系结构图 Executor组件分析 E ...

  8. 精尽MyBatis源码分析 - MyBatis 的 SQL 执行过程(一)之 Executor

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

  9. 精尽MyBatis源码分析 - 插件机制

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

随机推荐

  1. ACM Ignatius and the Princess II

    Problem Description Now our hero finds the door to the BEelzebub feng5166. He opens the door and fin ...

  2. Docker命令查询

    基本语法 docker [OPTIONS] COMMAND [arg...] 一般来说,Docker 命令可以用来管理 daemon,或者通过 CLI 命令管理镜像和容器.可以通过 man docke ...

  3. Rx系列二 | Observer | Observable

    Rx系列二 | Observer | Observable 上节课我们对RX的一些基本概念和使用JAVA代码实现了一个观察者,但是这只是对思路的一个讲解,在我们JAVA中,其实是已经封装好了观察者对象 ...

  4. Lucene查询结果高亮

    检索结果高亮 实现效果: 核心代码 package ucas.ir.lucene; import java.io.File; import java.io.IOException; import ja ...

  5. Dynamics CRM2016 Update or Create parentcustomerid in Contact using web api

    联系人实体中有个特殊的字段parentcustomerid 在通过web api创建或更新记录时,如果在给这个字段赋值时当做查找字段对待的话,那你就会遇到问题了,报错信息如下 正确的赋值方式如下

  6. Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43536355 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法 ...

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

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

  8. SpriteKit给游戏弹跳角色添加一个高度标示器

    这是一个类似于跳跃涂鸦的小游戏,主角不断吃能量球得到跳跃能量向更高的地方跳跃,如果图中碰到黑洞就挂了- 在游戏调试过程中如果能实时知道主角的高度就好了,这将有助于程序猿动态的判断游戏胜败逻辑. 你可以 ...

  9. C控制台实现模拟平抛运动算法

    平抛运动这个相信读了高中物理都知道这个概念了,详细的我就不说了,不明白的看看百度: 平抛运动 接下来看看用控制台实现的平抛运动算法: #include <stdio.h> #include ...

  10. mysql-workbench工具update(更新)失败的解决办法

    是因为安全模式的保护,所以我们需要设置一下: 如下:windows下是edit–>preferences–>SQL Editor 把右边的最后一行,"safe update&qu ...