一、mybatis-plus版本号
<spring-boot.mybatis-plus>3.4.3.1</spring-boot.mybatis-plus>
二、观点(是批量,但绝对不是按1000来批量)
1.先说网上的,一些人说是假的,说他是for循环单条记录插入;一些人说是真的,说真的那方说
// 5.批量插入
saveBatch(indexList, 1000);
该方法指定数量就按数量批量插入,没指定数量就默认批量每次一千条。他们都在拿各自版本源码分析
2.我没得时间去探究源码,说说实际操作。
- 19年就用过mybatis-plus最新版批量插入,当时数据量小,但打印的sql日志记得确实是for循环。
- 22年再次用了这个版本的批量插入方法,从打印的sql日志看它不是for循环单条插入,也不是按我指定的1000批量插入。而是几十条,几条等每次数量不固定的批量插入。我这次批量插入20多万条数据。用saveBatch(indexList, 1000);方法花费了接近25分钟。我感到不可思议(我的需求就是每天凌晨定时清空某个表,然后批量插入20多万数据,以后会是50万,100万,现在就25分钟,50万怕是得50分钟,等不了等不了)。于是我决定采用一下原始拼接1000条数据字符串方式,也没采用多线程,就单线程for循环20多万条数据,11秒就插入成功!
三、代码展示
// 5.批量插入(这个mybatis—plus方法太慢了,放弃!)
// saveBatch(indexList, 1000);
final String INSET_SQL = "INSERT INTO `dev_lift_index` (`id`, `lift_id`, `park_id`, `park_name`, `mc_corp_id`, `mc_corp_name`, `area_id`, `area_name`, `exp`, `has_mc`, `last_mc`) VALUES ";
// 标记,满1000就重置
int flag = 0;
StringBuilder sb = new StringBuilder("");
for (DevLiftIndex f : indexList) {
flag++;
sb.append("(").append("null,")
.append(f.getLiftId()).append(",")
.append(f.getParkId()).append(",")
.append("'").append(f.getParkName()).append("'").append(",")
.append(f.getMcCorpId()).append(",")
.append("'").append(f.getMcCorpName()).append("'").append(",")
.append(f.getAreaId()).append(",")
.append("'").append(f.getAreaName()).append("'").append(",")
.append(f.getExp()).append(",")
.append(f.getHasMc() == null ? false : f.getHasMc()).append(",")
.append(f.getLastMc() == null ? false : f.getLastMc()).append(")");
// 1.拼接 2.满1000就插入
if (flag == 1000) {
sb.append(";");
sb.insert(0,INSET_SQL);
baseMapper.batchInsertIndex(sb.toString());
flag = 0;
sb.setLength(0);
}else {
sb.append(",");
}
}
// 最后不足一千条的数据单独处理
if (sb.length()>1) {
sb.insert(0,INSET_SQL);
String substring = sb.toString().substring(0, sb.length()-1);
baseMapper.batchInsertIndex(substring + ";");
}
// 输出耗时
log.info("插入:" + timer.intervalRestart());