mybatis 的批量处理功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis 的批量处理功能相关的知识,希望对你有一定的参考价值。

由于在3.1.1升级后,可直接通过batchExcutor实现具体的批量执行。在该excutor中会重用上一次相同的prepareStatement。

/** 
 * 批量插入数据 <br/> 
 * 1、数据批量插入,默认一次提交100条,当发生异常后继续提交异常行以后的数据,待集合全部进行提交后返回批量处理结果<br/> 
 * 2、数据批量插入,如果需要回滚,当发生异常后,数据库异常即向外抛出,不会进行至全部执行后再抛出异常 <br/> 
 * <功能详细描述> 
 *  
 * @param statement 
 * @param objectCollection 
 * @param isRollback 
 * @return [参数说明] 
 *  
 * @return BatchResult<T> [返回类型说明] 
 * @exception throws [异常类型] [异常说明] 
 * @see [类、类#方法、类#成员] 
 */  
public BatchResult batchInsert(String statement, List<?> objectList,  
        boolean isStopWhenFlushHappenedException) {  
    return batchInsert(statement,  
            objectList,  
            defaultDoFlushSize,  
            isStopWhenFlushHappenedException);  
}  
  
/** 
 * 批量插入数据 
 *  
 * @param statement 
 * @param objectList 
 *            对象列表 
 * @param doFlushSize 
 * @param isStopWhenFlushHappenedException 
 *            当在flush发生异常时是否停止,如果在调用insert时抛出的异常,不在此设置影响范围内 
 * @return void [返回类型说明] 
 * @exception throws [异常类型] [异常说明] 
 * @see [类、类#方法、类#成员] 
 */  
// 批量插入  
public BatchResult batchInsert(String statement, List<?> objectList,  
        int doFlushSize, boolean isStopWhenFlushHappenedException) {  
    BatchResult result = new BatchResult();  
    if (CollectionUtils.isEmpty(objectList)) {  
        return result;  
    }  
    if (doFlushSize <= 0) {  
        doFlushSize = defaultDoFlushSize;  
    }  
    //设置总条数  
    result.setTotalNum(objectList.size());  
      
    //从当前环境中根据connection生成批量提交的sqlSession  
    SqlSession sqlSession = this.sqlSessionTemplate.getSqlSessionFactory()  
            .openSession(ExecutorType.BATCH);  
      
    try {  
        // 本次flush的列表开始行行索引  
        int startFlushRowIndex = 0;  
        for (int index = 0; index < objectList.size(); index++) {  
            // 插入对象  
            insertForBatch(sqlSession,  
                    statement,  
                    objectList.get(index),  
                    null);  
            if ((index > 0 && index % doFlushSize == 0)  
                    || index == objectList.size() - 1) {  
                try {  
                    List<org.apache.ibatis.executor.BatchResult> test = flushBatchStatements(sqlSession);  
                    System.out.println(test);  
                    startFlushRowIndex = index + 1;  
                }  
                catch (Exception ex) {  
                    if (!(ex.getCause() instanceof BatchExecutorException)  
                            || isStopWhenFlushHappenedException) {  
                        DataAccessException translated = this.sqlSessionTemplate.getPersistenceExceptionTranslator()  
                                .translateExceptionIfPossible((PersistenceException) ex);  
                        throw translated;  
                    }  
                      
                    BatchExecutorException e = (BatchExecutorException) ex.getCause();  
                    // 如果为忽略错误异常则记录警告日志即可,无需打印堆栈,如果需要堆栈,需将日志级别配置为debug  
                    logger.warn("batchInsert hanppend Exception:{},the exception be igorned.",  
                            ex.toString());  
                    if (logger.isDebugEnabled()) {  
                        logger.debug(ex.toString(), ex);  
                    }  
                      
                    // 获取错误行数,由于错误行发生的地方  
                    int errorRownumIndex = startFlushRowIndex  
                            + e.getSuccessfulBatchResults().size();  
                    result.addErrorInfoWhenException(objectList.get(index),  
                            errorRownumIndex,  
                            ex);  
                      
                    //将行索引调整为错误行的行号,即从发生错误的行后面一行继续执行  
                    index = errorRownumIndex;  
                    startFlushRowIndex = errorRownumIndex + 1;  
                }  
            }  
        }  
    }  
    finally {  
        sqlSession.close();  
    }  
    return result;  
}  

这里的实现写得稍微复杂一些,

主要是,针对有些情况如果其中某条失败,还想后续数据能够继续成功提交的情况进行支持。

以上是关于mybatis 的批量处理功能的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis动态SQL

SpringBoot+Mybatis实现批量添加功能

mybatis以及mybatisplus批量插入问题

Mybatis 实现批量插入和批量删除源码实例

DB2用mybatis批量update的问题

MySQL+MyBatis下批量修改数据的问题