网站搭建免费模板,做网站需要多少屏,网页制作模板大全,网站制作哈尔滨数据库批量入库方常见方式#xff1a;Java中foreach和xml中使用foreach
两者的区别#xff1a;
通过Java的foreach循环批量插入#xff1a;
当我们在Java通过foreach循环插入的时候#xff0c;是一条一条sql执行然后将事物统一交给spring的事物来管理#xff08;Transa…数据库批量入库方常见方式Java中foreach和xml中使用foreach
两者的区别
通过Java的foreach循环批量插入
当我们在Java通过foreach循环插入的时候是一条一条sql执行然后将事物统一交给spring的事物来管理Transactional,当遇到错误时候可以全部回滚。
缺点每次执行都会消耗网络io以及磁盘io执行效率很低。
通过xml中使用foreach批量插入
在xml中使用foreach会遍历生成一个sql语句然后一次发送到数据库只需要一次网络 io
如下所示
foreach collectionlist itemitem separator;insert into user(id, name, phone)values (#{id}, #{name}, #{phone})/foreach
缺点如果数据量过大则会生成一个很大的sql会导致io异常
上诉xml还有优化的写法如下: insert into user(id, name, phone)valuesforeach collectionlist itemitem separator,(#{id}, #{name}, #{phone})/foreach
两者的区别是在遍历的内容第一种写法会生成多条单独的插入sql语句insert into ,,,,,; insert into ....;,第二种是只遍历values后面的内容使用了insert into .... values 的语法减少了sql的大小。
除了以上的两种方法之外还可以自己手动实现一个批量插入或修改的工具类挺好用的
如下所示
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionSynchronizationManager;import java.util.List;
import java.util.function.BiFunction;/*** author light pwd* description* date 2024/10/25*/
Component
public class MyBatchUtils {private static final Logger LOG LoggerFactory.getLogger(MyBatchUtils.class);/*** 每次处理1000条*/private static final int BATCH_SIZE 1000;Autowiredprivate SqlSessionFactory sqlSessionFactory;/*** 批量处理修改或者插入* 变成一条一条的数据然后最后一起执行。并不是 insertBatch那种方式* param data 需要被处理的数据* param mapperClass Mybatis的Mapper类* param function 自定义处理逻辑* return int 影响的总行数*/public T, U, R int batchUpdateOrInsert(ListT data, ClassU mapperClass, BiFunctionT, U, R function) {int i 1;SqlSession batchSqlSession sqlSessionFactory.openSession(ExecutorType.BATCH);try {U mapper batchSqlSession.getMapper(mapperClass);int size data.size();for (T element : data) {function.apply(element, mapper);if (i % BATCH_SIZE 0 || i size) {batchSqlSession.flushStatements();}i;}// 非事务环境下强制commit事务情况下该commit相当于无效交给spring的事物来管理batchSqlSession.commit(!TransactionSynchronizationManager.isSynchronizationActive());} catch (Exception e) {batchSqlSession.rollback();LOG.error(e.getMessage());throw BusinessException.of(CommonErrorCodes.RUN_TIME_EXCEPTION, MybatisBatchUtilsException);} finally {batchSqlSession.close();}return i - 1;}
}该方法既结合了Java种foreach的优势又结合了在xml种foreach的优势。这种方式与mybatis-plus的insertBatch是不同的mybatis-plus默认提供的insertBatch方法本质是一条一条sql执行然后一起提交。
该方法对于大数据量会自动分批插入每次1000条的插入到数据库省去了分批处理。
用法也很简单 batchUtils.batchUpdateOrInsert(haveIdColumn, PreColumnConfigMapper.class,(item, mapper) - mapper.updateOne(item, createTime, createrId));batchUtils.batchUpdateOrInsert(noIdLine, PreLineConfigMapper.class,(item, mapper) - mapper.insertOne(item, createTime, createrId)); 其中batchUtils就是通过spring注入进来的MyBatchUtils的beanhaveIdColumn/noIdLine是一个待插入的List数据PreLineConfigMapper/PreColumnConfigMapper都是mapper文件 他们得updateOne和insertOne xml方法如下所示我是pg数据库mysql是类似的 update idupdateOne parameterTypecom.jiuaoedu.serviceeducation.pre.pojo.PreColumnConfigupdate service_education.pre_column_configset type #{bean.type,jdbcTypeVARCHAR}, grade #{bean.grade,jdbcTypeVARCHAR}, subject #{bean.subject,jdbcTypeVARCHAR},name #{bean.name,jdbcTypeVARCHAR}, name_id #{bean.nameId,jdbcTypeVARCHAR},order_num #{bean.orderNum,jdbcTypeINTEGER},creater_id #{createrId,jdbcTypeBIGINT},create_time #{createTime,jdbcTypeTIMESTAMP}, target_num null, class_num null, del 1where column_id #{bean.columnId,jdbcTypeBIGINT}/update insert idinsertOne parameterTypecom.jiuaoedu.serviceeducation.pre.pojo.PreLineConfiginsert into service_education.pre_line_config(plan_id, group_id, title,type, start_date, end_date, start_time, end_time, week, order_num,count_date,year,term, time_order, create_time, creater_id)values(#{bean.planId,jdbcTypeBIGINT},#{bean.groupId,jdbcTypeVARCHAR}, #{bean.title,jdbcTypeVARCHAR},#{bean.type,jdbcTypeVARCHAR},#{bean.startDate,jdbcTypeTIMESTAMP}, #{bean.endDate,jdbcTypeTIMESTAMP},#{bean.startTime,jdbcTypeTIME},#{bean.endTime,jdbcTypeTIME},#{bean.week,jdbcTypeVARCHAR},#{bean.orderNum,jdbcTypeINTEGER}, #{bean.countDate,jdbcTypeTIMESTAMP},#{bean.year,jdbcTypeINTEGER},#{bean.term,jdbcTypeVARCHAR}, #{bean.timeOrder,jdbcTypeINTEGER},#{createTime,jdbcTypeTIMESTAMP}, #{createrId,jdbcTypeBIGINT})/insert 注意事项当在有事物的方法A中使用MyBatchUtils 工具类的时候工具类的事物是跟方法A同步的即方法A回滚则执行的所有数据都会回滚 当在没有事物的方法A中使用时因为MyBatchUtils 会分批次插入所以每批次会有一个事物提交也是一个批次一起提交回滚也只回滚一个批次 奋斗不止进步无止境让人生在追求中焕发光彩