Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。


方法一:使用 XML 的 <foreach> 标签(推荐)

这是最高效的方式,通过单条 SQL 语句一次性插入多条数据。

1. Mapper 接口

java

复制

下载

@Mapper
public interface UserMapper {// 批量插入方法int batchInsert(@Param("users") List<User> users);
}
2. XML 映射文件 (UserMapper.xml)

xml

复制

下载

运行

<insert id="batchInsert">INSERT INTO user (name, email, age)VALUES<foreach collection="users" item="user" separator=",">(#{user.name}, #{user.email}, #{user.age})</foreach>
</insert>
3. Service 层实现

java

复制

下载

@Service
@RequiredArgsConstructor // Lombok 注解
public class UserService {private final UserMapper userMapper;@Transactionalpublic void batchInsertUsers(List<User> users) {if (users != null && !users.isEmpty()) {userMapper.batchInsert(users);}}
}
4. 实体类

java

复制

下载

@Data // Lombok 注解
public class User {private Long id;private String name;private String email;private Integer age;
}

方法二:使用 MyBatis 批处理模式

适合需要精确控制事务的场景,但性能略低于 <foreach> 方式。

1. Mapper 接口

java

复制

下载

@Mapper
public interface UserMapper {// 单条插入方法void insert(User user);
}
2. XML 映射文件

xml

复制

下载

运行

<insert id="insert">INSERT INTO user (name, email, age)VALUES (#{name}, #{email}, #{age})
</insert>
3. Service 层实现

java

复制

下载

@Service
@RequiredArgsConstructor
public class UserService {private final SqlSessionTemplate sqlSessionTemplate;@Transactionalpublic void batchInsert(List<User> users) {// 获取批处理模式的 SqlSessionSqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false); // 关闭自动提交try {UserMapper mapper = sqlSession.getMapper(UserMapper.class);for (User user : users) {mapper.insert(user);}sqlSession.commit(); // 手动提交} catch (Exception e) {sqlSession.rollback();throw e;} finally {sqlSession.close();}}
}

关键配置

1. application.yml 配置

yaml

复制

下载

spring:datasource:url: jdbc:mysql://localhost:3306/test?useSSL=false&rewriteBatchedStatements=true # MySQL 批处理优化username: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Drivermybatis:mapper-locations: classpath:mapper/*.xml # XML 文件位置
2. 添加依赖 (pom.xml)

xml

复制

下载

运行

<dependencies><!-- Spring Boot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- MyBatis + Spring Boot --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version></dependency><!-- MySQL 驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
</dependencies>

性能优化建议

  1. MySQL 参数:在 JDBC URL 中添加 rewriteBatchedStatements=true,启用真正的批处理(提升 5-10 倍性能)。

  2. 批次大小:每批处理 500-1000 条数据(避免 SQL 过长)。

  3. 事务控制:确保在 Service 层使用 @Transactional

  4. 连接池:使用 HikariCP 等高性能连接池(Spring Boot 默认集成)。


两种方法对比

方法优点缺点
<foreach> 标签单次数据库交互,性能最高超大数据可能使 SQL 过长
ExecutorType.BATCH灵活控制事务,内存占用低需要手动提交,性能略低

根据数据量选择合适方案:

  • 数据量 < 1000:推荐 <foreach>

  • 数据量 > 10000:推荐分批次 + <foreach>(每批 500 条)

项目实例:

BranchWarehouseApplyServiceImpl.java
    // 生成分仓物资申领(试剂耗材)@Overridepublic void generateDetailForReagent(List<ReagentOptionVO> reagentOptionList) {// 获取用户名(账号)String userName = PublicUtils.getUserName();// 通过用户名(账号),获取其所属部门Department department = departmentMapper.selectByUserName(userName);List<BranchWarehouseApplyDetail> applyDetailList = new ArrayList<>();reagentOptionList.forEach(item -> {BranchWarehouseApplyDetail applyDetail = new BranchWarehouseApplyDetail();applyDetail.setWarehouseId(1);applyDetail.setMaterialId(item.getId());applyDetail.setApplyTime(LocalDateTime.now());applyDetail.setApplyDept(department.getDeptId());applyDetail.setApplyOperator(userName);applyDetail.setAmount(item.getApplyAmount());applyDetail.setStage(0);applyDetailList.add(applyDetail);});// 集合不为空if (!applyDetailList.isEmpty()) {// 批处理,拆分数据,满50条,执行批量插入List<List<BranchWarehouseApplyDetail>> lists = (List<List<BranchWarehouseApplyDetail>>)PublicUtils.splitList(applyDetailList, 50);for (List<BranchWarehouseApplyDetail> list: lists) {branchWarehouseApplyMapper.insertDetail(list);}}}
BranchWarehouseApplyMapper.java
@Mapper
public interface BranchWarehouseApplyMapper {// 批量增加分仓物资申领void insertDetail(List<BranchWarehouseApplyDetail> applyDetailList);
}

 BranchWarehouseApplyMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.weiyu.mapper.BranchWarehouseApplyMapper"><!-- 分仓物资申领 mssql --><!-- 批量增加分仓物资申领,使用单条INSERT语句配合VALUES列表更高效 --><insert id="insertDetail">insert into BranchWarehouseApplyDetail (warehouse_id, material_id, apply_time, apply_dept, apply_operator,amount, purpose, stage, remark)<!-- 非空列表,并且有记录 --><if test="applyDetailList != null and applyDetailList.size() > 0">values<foreach collection="applyDetailList" item="item" separator=",">(#{item.warehouseId}, #{item.materialId}, #{item.applyTime}, #{item.applyDept}, #{item.applyOperator},#{item.amount}, #{item.purpose}, #{item.stage}, #{item.remark})</foreach></if><!-- 空集合安全处理:当传入空列表时,确保不插入实际数据,同时避免数据库报错 --><if test="applyDetailList == null or applyDetailList.size() == 0">selectnull, null, null, null, null, null, null, null, nullwhere 1 = 0</if></insert>
</mapper>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/86461.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包

通过Cline使用智能体

文章目录 1、VS Code配置2、Cline使用2.1 工作模式2.2 MCP服务2.3 Cline支持的服务 3、案例一&#xff1a;天气查询项目3.1 需求说明3.2 申请高德API Key3.3 实操&#xff1a;向Cline下达命令 4、案例二&#xff1a;双城天气对比项目4.1 需求说明4.2 实操 Cline是VS Code的插件…

「混合开发」H5与原生App交互流程方案全面解析

目录 内嵌H5调用iOS内的方法 1. 背景 2. 解决方案 2.1 创建WebView 2.2 注册原生方法 2.3 H5调用原生方法 3. 序列图 H5 调用 Android&#xff1a;详细指南 整体流程 每一步的详细说明 步骤1&#xff1a;在Android项目中设置WebView 步骤2&#xff1a;定义JavaScri…

webpack打包vue项目

要在 Vue 项目中使用 Webpack 进行打包&#xff0c;通常有几种不同的方式来设置你的项目。以下是基本步骤&#xff1a; 1. 使用 Vue CLI 创建项目&#xff08;推荐&#xff09; Vue CLI 是官方提供的一个脚手架工具&#xff0c;它内置了对 Webpack 的支持&#xff0c;并且简化…

Linux环境-通过命令查看zookeeper注册的服务

假设前置条件如下&#xff1a; 1.root权限用户名&#xff1a;zookeeper 2.zookeeper所在服务器地址&#xff1a;168.7.3.254&#xff08;非真实ip&#xff09; 3.zookeeper的bin文件路径&#xff1a;/opt/zookeeper/bin 4.确保zookeeper注册中心已启动 查看注册中心服务如下&a…

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…

ArcGIS计算多个栅格数据的平均栅格

3种方法计算多个栅格数据的平均栅格 1->使用“ 栅格计算器”工具 原理就是把多幅影像数据相加&#xff0c;然后除以个数&#xff0c;就能得到平均栅格。 2-> 使用“像元统计数据”工具&#xff0c;如果是ArcGIS pro&#xff0c;则是“像元统计”工具。使用这个工具可以…

Ubantu-Docker配置最新镜像源250605

尝试其他镜像加速器 阿里云镜像加速器&#xff1a;登录阿里云&#xff0c;进入容器镜像服务获取专属加速器地址。毫秒镜像&#xff1a;https://docker.1ms.run。DockerHub镜像加速器&#xff1a;https://docker.xuanyuan.me。Docker Hub 镜像加速服务&#xff1a;https://dock…

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…

Unity网络通信笔记

需求 首先要意识到网络通信面对的是一个怎么样的情景&#xff1a; 服务器会连任意个客户端&#xff0c;任意时刻可能有客户端连入连出&#xff1b;服务端和客户端可能任意时刻给对方发消息&#xff0c;所以双方都要一直准备好接收。但是两端还有别的事要做&#xff0c;通信不…

EasyRTC嵌入式音视频通信SDK音视频功能驱动视频业务多场景应用

一、方案背景​ 随着互联网技术快速发展&#xff0c;视频应用成为主流内容消费方式。用户需求已从高清流畅升级为实时互动&#xff0c;EasyRTC作为高性能实时音视频框架&#xff0c;凭借低延迟、跨平台等特性&#xff0c;有效满足市场对多元化视频服务的需求。 二、EasyRTC技术…

《MLB美职棒》勇士队排名·棒球1号位

亚特兰大勇士队&#xff08;Atlanta Braves&#xff09;是美国职业棒球大联盟&#xff08;MLB&#xff09;中历史最悠久的球队之一&#xff0c;隶属于国家联盟&#xff08;NL&#xff09;东区。 球队基本信息 成立时间&#xff1a;1871年&#xff08;前身为波士顿红袜帽队&…

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…

每日一令:Linux 极简通关指南 - 汇总

专栏列表 &#x1f4bb; 每日一令&#xff1a;Linux 极简通关指南 (25篇) 【基础】每天掌握一个Linux命令 - nsenter&#xff1a;深入容器与命名空间的利器 发布于 2025-06-08 22:27:04【基础】 每天掌握一个Linux命令 - journalctl&#xff1a;系统日志管理的得力助手 发布于…

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术点解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术点解析 第一轮&#xff1a;基础概念问题 请解释Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; 程序员JY回答&#xff1a;Spring框架的核心容器是IoC容器&#xff08;控制反转…

渗透测试服务如何全方位评估企业安全状况并揭示潜在缺陷?

渗透测试服务通过模拟攻击行为&#xff0c;对企业整体安全状况进行全方位评估&#xff0c;旨在揭示潜在的安全缺陷并制定相应的修复措施。以下为渗透测试服务报告的核心内容。 测试类型适配 外部渗透测试旨在模仿外部网络攻击者&#xff0c;尝试突破企业网络安全防线&#xf…

SwiftUI 数据绑定与视图更新(@State、@ObservedObject、@EnvironmentObject)

引言 在 SwiftUI 中&#xff0c;界面并不是通过手动刷新来更新的&#xff0c;而是由状态驱动的。当状态发生变化&#xff0c;SwiftUI 会自动识别哪些视图需要重绘&#xff0c;从而保持 UI 与数据的一致性。这种声明式的方式大大简化了界面开发的流程&#xff0c;但也带来一个问…

21-Oracle 23 ai-Automatic SQL Plan Management(SPM)

小伙伴们&#xff0c;有没有迁移数据库完毕后或是突然某一天在同一个实例上同样的SQL&#xff0c; 性能不一样了、业务反馈卡顿、业务超时等各种匪夷所思的现状。 于是SPM定位开始&#xff0c;OCM考试中SPM必考。 其他的AWR、ASH、SQLHC、SQLT、SQL profile等换作下一个话题…

[Linux] 命令行管理文件

目录 FHS 文件路径导航 ls命令 tree命令 stat命令 touch命令 命令行管理文件 mkdir命令 cp命令 mv命令 rm和rmdir命令 软链接 硬链接 软连接硬链接区别 shell扩展匹配文件 FHS FHS采用树形结构组织文件&#xff0c;定义了系统中每个区域的用途、所需要的最小构…

自动化过程中,如何定位一闪而过的toast?

MutationObserver实战&#xff1a;动态捕获页面Toast消息的终极解决方案 一、代码全景解析 const observer new MutationObserver((mutations) > {// 回调函数主体... });observer.observe(document.body, {childList: true,subtree: true });核心组件解析 组件作用重要…