1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
| public interface IService<T> { int DEFAULT_BATCH_SIZE = 1000;
@Transactional( rollbackFor = {Exception.class} ) default boolean saveBatch(Collection<T> entityList) { return this.saveBatch(entityList, 1000); } boolean saveBatch(Collection<T> entityList, int batchSize);
@Transactional( rollbackFor = {Exception.class} ) default boolean saveOrUpdateBatch(Collection<T> entityList) { return this.saveOrUpdateBatch(entityList, 1000); } boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
@Transactional( rollbackFor = {Exception.class} ) default boolean updateBatchById(Collection<T> entityList) { return this.updateBatchById(entityList, 1000); } boolean updateBatchById(Collection<T> entityList, int batchSize); }
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
@Transactional( rollbackFor = {Exception.class} ) public boolean saveBatch(Collection<T> entityList, int batchSize) { String sqlStatement = this.getSqlStatement(SqlMethod.INSERT_ONE); return this.executeBatch(entityList, batchSize, (sqlSession, entity) -> { sqlSession.insert(sqlStatement, entity); }); }
@Transactional( rollbackFor = {Exception.class} ) public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) { TableInfo tableInfo = TableInfoHelper.getTableInfo(this.entityClass); Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!", new Object[0]); String keyProperty = tableInfo.getKeyProperty(); Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!", new Object[0]); return SqlHelper.saveOrUpdateBatch(this.entityClass, this.mapperClass, this.log, entityList, batchSize, (sqlSession, entity) -> { Object idVal = ReflectionKit.getFieldValue(entity, keyProperty); return StringUtils.checkValNull(idVal) || CollectionUtils.isEmpty(sqlSession.selectList(this.getSqlStatement(SqlMethod.SELECT_BY_ID), entity)); }, (sqlSession, entity) -> { ParamMap<T> param = new ParamMap(); param.put("et", entity); sqlSession.update(this.getSqlStatement(SqlMethod.UPDATE_BY_ID), param); }); }
@Transactional( rollbackFor = {Exception.class} ) public boolean updateBatchById(Collection<T> entityList, int batchSize) { String sqlStatement = this.getSqlStatement(SqlMethod.UPDATE_BY_ID); return this.executeBatch(entityList, batchSize, (sqlSession, entity) -> { ParamMap<T> param = new ParamMap(); param.put("et", entity); sqlSession.update(sqlStatement, param); }); }
@Deprecated protected boolean executeBatch(Consumer<SqlSession> consumer) { return SqlHelper.executeBatch(this.entityClass, this.log, consumer); }
protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) { return SqlHelper.executeBatch(this.entityClass, this.log, list, batchSize, consumer); }
protected <E> boolean executeBatch(Collection<E> list, BiConsumer<SqlSession, E> consumer) { return this.executeBatch(list, 1000, consumer); } }
public final class SqlHelper { public static boolean executeBatch(Class<?> entityClass, Log log, Consumer<SqlSession> consumer) { SqlSessionFactory sqlSessionFactory = sqlSessionFactory(entityClass); SqlSessionHolder sqlSessionHolder = (SqlSessionHolder)TransactionSynchronizationManager.getResource(sqlSessionFactory); boolean transaction = TransactionSynchronizationManager.isSynchronizationActive(); SqlSession sqlSession; if (sqlSessionHolder != null) { sqlSession = sqlSessionHolder.getSqlSession(); sqlSession.commit(!transaction); }
sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); if (!transaction) { log.warn("SqlSession [" + sqlSession + "] was not registered for synchronization because DataSource is not transactional"); }
boolean var7; try { consumer.accept(sqlSession); sqlSession.commit(!transaction); var7 = true; } catch (Throwable var13) { sqlSession.rollback(); Throwable unwrapped = ExceptionUtil.unwrapThrowable(var13); if (unwrapped instanceof RuntimeException) { MyBatisExceptionTranslator myBatisExceptionTranslator = new MyBatisExceptionTranslator(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true); throw (DataAccessException)Objects.requireNonNull(myBatisExceptionTranslator.translateExceptionIfPossible((RuntimeException)unwrapped)); }
throw ExceptionUtils.mpe(unwrapped); } finally { sqlSession.close(); }
return var7; }
public static <E> boolean executeBatch(Class<?> entityClass, Log log, Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) { Assert.isFalse(batchSize < 1, "batchSize must not be less than one", new Object[0]); return !CollectionUtils.isEmpty(list) && executeBatch(entityClass, log, (sqlSession) -> { int size = list.size(); int i = 1;
for(Iterator var6 = list.iterator(); var6.hasNext(); ++i) { E element = var6.next(); consumer.accept(sqlSession, element); if (i % batchSize == 0 || i == size) { sqlSession.flushStatements(); } }
}); } }
|