1. 程式人生 > >mybatis 的批量處理功能

mybatis 的批量處理功能

設置 light col cep 錯誤 復雜 param etc cut

由於在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 的批量處理功能