mybatis 的批量處理功能
阿新 • • 發佈:2017-09-13
設置 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 的批量處理功能