IService批量新增:
先在测试类里面写一个增加10w条用户的方法
private User buildUser(int i){
User user = new User();
user.setUsername("user_"+i);
user.setPassword("123");
user.setPhone(""+(18833703503L + i));
user.setBalance(2000);
user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");
user.setCreateTime(LocalDateTime.now());
user.setUpdateTime(user.getCreateTime());
return user;
}
@Test
void testSaveOneByOne(){
long b = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
userService.save(buildUser(i));
}
long e = System.currentTimeMillis();
System.out.println("耗时:"+(e-b)+"毫秒");
}
启动一下测试类看一看新增10w条用户用了多长时间
虽然新增成功了,但是时间实在是太长了,所以我们来用一下IService的批量新增功能优化一下
@Test
void testSaveBatch(){
//我们每次批量插入1000条,插入100次即10万条数据
//1.准备一个容量为1000的集合
List<User> list = new ArrayList<>(1000);
long b = System.currentTimeMillis();
for (int i = 0; i < 100000; i++){
//1.添加一个user
list.add(buildUser(i));
//2.判断集合是否达到1000,达到则批量插入
if (list.size() == 1000){
userService.saveBatch(list);
//3.清空集合,准备下一批数据
list.clear();
}
}
long e = System.currentTimeMillis();
System.out.println("耗时:"+(e-b)+"毫秒");
}
逻辑就是创建一个容量为1000的集合,让这个集合插入100次达到批量插入的效果,在循环之中记得写清空集合的语句,为下一批数据做准备。
我们可以看到执行的时间是10426毫秒,可见效率提升了非常多。
但是这样再实用之中会预编译,会先预编译成sql语句,所以就会出现1000条sql语句,每1000条发送一次网络请求,但是在mysql在执行时是逐条执行的,如果这1000条数据不是1000条sql语句insert而是转换成1条sql语句一次性插入到数据库,这才是真正的批量插入,就要想办法把sql语句变成这个样子
那么我们该怎么样操作呢--1.动态sql,自定义sql语句,利用foreach标签遍历这1000条数据,遍历的过程中再组装成这个样子
2.开启rewriteBatchedStatements=true参数(重写批处理的语句),这个值默认是false,虽然看似你在使用批处理,但是提交的sql语句还是一条一条的。
我们只需要在yaml文件里jdbc后面拼上rewriteBatchedStatements=true即可,代码不用动。
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
我们可以看到耗时只需要4672毫秒,非常好用!
代码生成器:
我们可以安装一个插件,当然也可以用Mybatis-Plus官方提供的MybatisPlusX插件
然后链接数据库我用的2024版idea,在tool下面有个configdeatabase,老版本的idea在下载完插件以后会多出来一个other选项卡,在那里面选择即可
第二步选择code generator进行下面的配置
代码已经生成好了,非常好用!