• Mybatis批量处理


    可以通过全局配置文件指定默认的Executor开启批量处理模式:

    <setting name="defaultExecutorType" value="BATCH"/>
    

    如果在全局配置文件中指定的话BATCH模式的话,所有的其他不需要批量处理的sql,都默认使用了Batch模式,所以正常情况下在应该在获取sqlSession的时候指定使用Batch类型的Executor,而不应该在全局配置文件配置:

    @Test
    public void testBatch() throws IOException{
       SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
       
       //可以执行批量操作的sqlSession
       SqlSession openSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
       long start = System.currentTimeMillis();
       try{
          EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
          for (int i = 0; i < 10000; i++) {
             mapper.addEmp(new Employee(UUID.randomUUID().toString().substring(0, 5), "b", "1"));
          }
          openSession.commit();
          long end = System.currentTimeMillis();
          System.out.println("执行时长:"+(end-start));//批量模式 执行时长4598,非批量模式 执行时长10200
       }finally{
          openSession.close();
       }
       
    }
    

    很明显,批量模式插入有更高的效率,大概看看BatchExecutor的源码了解其原因:

    @Override
    public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLException {
      final Configuration configuration = ms.getConfiguration();
      final StatementHandler handler = configuration.newStatementHandler(this, ms, parameterObject, RowBounds.DEFAULT, null, null);
      final BoundSql boundSql = handler.getBoundSql();
      final String sql = boundSql.getSql();
      final Statement stmt;
      
      //判断MappedStatement和sql语句是否和缓存的一致
      if (sql.equals(currentSql) && ms.equals(currentStatement)) {
        int last = statementList.size() - 1;
        //获取上一次已经预编译过的PreparedStatement(主要优化)
        stmt = statementList.get(last);
        applyTransactionTimeout(stmt);
        //设置sql参数
        handler.parameterize(stmt);
        BatchResult batchResult = batchResultList.get(last);
        //保存每次传入的参数
        batchResult.addParameterObject(parameterObject);
      } else {//首次执行
        //获取连接
        Connection connection = getConnection(ms.getStatementLog());
        //预编译sql,获取PreparedStatement
        stmt = handler.prepare(connection, transaction.getTimeout());
        //设置sql参数
        handler.parameterize(stmt); 
        //缓存当前sql语句
        currentSql = sql;
        //缓存MappedStatement(代表增删改查标签的所有信息)
        currentStatement = ms;
        //保存PreparedStatement
        statementList.add(stmt);
        batchResultList.add(new BatchResult(ms, sql, parameterObject));
      }
      handler.batch(stmt);
      return BATCH_UPDATE_RETURN_VALUE;
    }
    

    主要的差别:

    批量模式:(预编译sql一次==>设置参数10000次===>执行1次)

    非批量模式:每插入一条记录都要完整的执行(预编译sql==>设置参数==>执行)10000次

  • 相关阅读:
    c++开发之对应Linux下的sem_t和lock
    嵌入式开发之davinci--- 8148/8168/8127 中的图像处理算法优化库vlib
    crc32 冗余加密校验
    快速安装 GitLab 并汉化
    oracle-6-密码文件
    oracle-5-的升级步骤
    Linux大文件已删除,但df查看已使用的空间并未减少解决
    cygwin 的不同文件类型显示不同的颜色
    PLSQL的安装
    网络流量监控工具----iftop
  • 原文地址:https://www.cnblogs.com/qzlcl/p/11335478.html
Copyright © 2020-2023  润新知