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 的批量处理功能的主要内容,如果未能解决你的问题,请参考以下文章