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>
性能优化建议
-
MySQL 参数:在 JDBC URL 中添加
rewriteBatchedStatements=true
,启用真正的批处理(提升 5-10 倍性能)。 -
批次大小:每批处理 500-1000 条数据(避免 SQL 过长)。
-
事务控制:确保在 Service 层使用
@Transactional
。 -
连接池:使用 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>
相关文章:
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...

springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...

算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...