当前位置: 首页 > news >正文

41. 如何在MyBatis-Plus中实现批量操作?批量插入和更新的最佳实践是什么?

在 MyBatis-Plus 中,实现批量操作(如批量插入、批量更新)是非常常见的需求。MyBatis-Plus 提供了对批量操作的良好支持,可以通过多种方式实现高效的批量处理。下面详细介绍批量操作的实现方式以及最佳实践。

1. 批量插入

批量插入是指一次性插入多条记录,而不是逐条插入。MyBatis-Plus 提供了多种方式来实现批量插入。

1.1 使用 insertBatchSomeColumn 方法

MyBatis-Plus 提供了 insertBatchSomeColumn 方法,可以直接插入一个集合的所有元素。这个方法通常用于插入时可以选择性地忽略一些不需要的字段(如主键自增的场景)。

示例:

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
​
@Service
public class UserService extends ServiceImpl<UserMapper, User> {
​public boolean batchInsert(List<User> userList) {return this.saveBatch(userList);}
}

调用示例:

List<User> userList = new ArrayList<>();
userList.add(new User("Alice", 25));
userList.add(new User("Bob", 30));
​
userService.batchInsert(userList);
  • saveBatch:MyBatis-Plus 提供的 saveBatch 方法可以一次性插入多个记录。该方法默认使用了批量插入的 SQL 优化,可以在一定程度上减少数据库的连接开销。

1.2 使用 Mapper 接口的批量插入

你也可以通过在 Mapper 接口中自定义批量插入的 SQL 语句来实现批量插入操作。

自定义批量插入 SQL:

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import java.util.List;
​
public interface UserMapper extends BaseMapper<User> {
​@Insert("<script>" +"INSERT INTO user (name, age) VALUES " +"<foreach collection='list' item='user' separator=','>" +"(#{user.name}, #{user.age})" +"</foreach>" +"</script>")int batchInsert(@Param("list") List<User> userList);
}

调用示例:

List<User> userList = new ArrayList<>();
userList.add(new User("Alice", 25));
userList.add(new User("Bob", 30));
​
userMapper.batchInsert(userList);
  • <foreach> 标签:在 MyBatis 的 XML 中使用 <foreach> 标签遍历集合,并生成批量插入的 SQL 语句。

2. 批量更新

批量更新指的是一次性更新多条记录。与批量插入类似,MyBatis-Plus 也提供了多种方式实现批量更新。

2.1 使用 updateBatchById 方法

MyBatis-Plus 提供了 updateBatchById 方法,支持根据 ID 批量更新多个实体。

示例:

@Service
public class UserService extends ServiceImpl<UserMapper, User> {
​public boolean batchUpdate(List<User> userList) {return this.updateBatchById(userList);}
}

调用示例:

List<User> userList = new ArrayList<>();
userList.add(new User(1L, "Alice", 26)); // 更新ID为1的用户
userList.add(new User(2L, "Bob", 31)); // 更新ID为2的用户
​
userService.batchUpdate(userList);
  • updateBatchById:该方法会根据传入的实体集合中的 ID,依次更新对应的记录。每个实体只更新有变动的字段。

2.2 自定义批量更新 SQL

你也可以通过在 Mapper 接口中自定义批量更新的 SQL 语句来实现批量更新操作。

自定义批量更新 SQL:

import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.annotations.Param;
import java.util.List;
​
public interface UserMapper extends BaseMapper<User> {
​@Update("<script>" +"<foreach collection='list' item='user' separator=';'>" +"UPDATE user " +"SET name = #{user.name}, age = #{user.age} " +"WHERE id = #{user.id}" +"</foreach>" +"</script>")int batchUpdate(@Param("list") List<User> userList);
}

调用示例:

List<User> userList = new ArrayList<>();
userList.add(new User(1L, "Alice", 26));
userList.add(new User(2L, "Bob", 31));
​
userMapper.batchUpdate(userList);
  • <foreach> 标签:与批量插入类似,使用 <foreach> 标签遍历集合并生成批量更新的 SQL 语句。

3. 批量操作的最佳实践

  1. 使用批量操作方法:MyBatis-Plus 提供的 saveBatchupdateBatchById 方法已经优化了 SQL 执行的效率,建议优先使用这些方法。

  2. 控制批量操作的大小:在批量插入或更新时,最好控制单次操作的批量大小(例如每次操作 1000 条记录),以避免 SQL 语句过长或数据库连接超时问题。

  3. 考虑使用数据库事务:批量操作通常需要涉及多条 SQL 语句的执行,为了保证操作的原子性,可以考虑在批量操作时使用数据库事务。

  4. 使用乐观锁:如果批量更新操作涉及并发写入,建议使用乐观锁来避免数据冲突,MyBatis-Plus 支持通过 @Version 注解实现乐观锁机制。

  5. 合理配置 MyBatis-Plus 插件:在高并发场景下,合理配置 MyBatis-Plus 的分页、乐观锁、SQL 性能分析等插件,可以提高应用的性能和稳定性。

总结

  • 批量插入:可以通过 MyBatis-Plus 的 saveBatch 方法实现,或者通过自定义 Mapper 接口的批量插入 SQL 语句实现。

  • 批量更新:可以通过 MyBatis-Plus 的 updateBatchById 方法实现,或者通过自定义 Mapper 接口的批量更新 SQL 语句实现。

  • 最佳实践:在批量操作中,合理控制批量大小、使用事务、应用乐观锁,以及配置好插件,可以确保批量操作的高效和稳定。

MyBatis-Plus 为批量操作提供了简便的接口和优化手段,使得开发者可以更加高效地处理大批量数据的插入和更新操作。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 解决DockerDesktop启动redis后采用PowerShell终端操作
  • C++初阶-list用法总结
  • 免费在线压缩pdf 压缩pdf在线免费 推荐简单好用
  • 【CTF】Nginx日志注入
  • 【算法题】63. 不同路径 II-力扣(LeetCode)-”如果起点有障碍物,那么便到不了终点“
  • WebGL颜色与纹理
  • 【制作100个unity游戏之32】unity开发属于自己的一个2d/3d桌面宠物,可以实时计算已经获取的工资
  • QT快速安装使用指南
  • Linux学习/复习2--Linux工具
  • 解决 npm ERR! node-sass 和 gyp ERR! node-gyp 报错问题
  • 蓝桥杯15届C/C++B组省赛题目
  • 【深入学习Redis丨第六篇】Redis哨兵模式与操作详解
  • 【Taro】初识 Taro
  • MyBatis系统学习(四)——MyBatis的关联映射和缓存机制
  • 摆脱困境并在 Android 手机上取回删除照片的所有解决方案
  • 【css3】浏览器内核及其兼容性
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • 【知识碎片】第三方登录弹窗效果
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • Cookie 在前端中的实践
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • webpack+react项目初体验——记录我的webpack环境配置
  • Web标准制定过程
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 分布式熔断降级平台aegis
  • 构建工具 - 收藏集 - 掘金
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • #Z0458. 树的中心2
  • #职场发展#其他
  • (10)ATF MMU转换表
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (C)一些题4
  • (C语言)字符分类函数
  • (Java入门)抽象类,接口,内部类
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (十二)Flink Table API
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (四)stm32之通信协议
  • (转)Oracle 9i 数据库设计指引全集(1)
  • (转)Unity3DUnity3D在android下调试
  • ****Linux下Mysql的安装和配置
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .Net Core缓存组件(MemoryCache)源码解析
  • .net framework profiles /.net framework 配置
  • .NET Framework、.NET Core 、 .NET 5、.NET 6和.NET 7 和.NET8 简介及区别
  • .Net Winform开发笔记(一)
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • .NET 读取 JSON格式的数据
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .Net7 环境安装配置
  • .NET中使用Protobuffer 实现序列化和反序列化