Java批量插入应使用PreparedStatement批处理而非手动拼接SQL,因其可防止SQL注入、自动处理转义与null、避免语法错误,并配合rewriteBatchedStatements=true等配置提升性能。

Java 中批量插入数据不建议手动拼接 SQL 字符串,尤其涉及用户输入时极易引发 SQL 注入、类型转换错误、引号转义混乱等问题。真正安全高效的做法是使用预编译参数(PreparedStatement)配合 addBatch() / executeBatch(),或借助 MyBatis、JDBC 批处理配置等成熟方案。
为什么不要手动拼接 INSERT SQL?
手动拼接(如 "INSERT INTO user(name,age) VALUES ('"+name+"',"+age+")")存在严重隐患:
- 遇到名字含单引号(如
O'Connor)会直接导致 SQL 语法错误 - 数值字段若为空或非数字,运行时报
NumberFormatException - 无法防止 SQL 注入——恶意输入可闭合引号并追加任意语句
- 字符串需要手动转义、日期需格式化、NULL 值难统一处理
- 大量字符串拼接性能差,还容易因括号/逗号位置出错
推荐做法:用 PreparedStatement 批处理
这是 JDBC 原生、安全、通用的批量插入方式:
String sql = "INSERT INTO user(name, age, email) VALUES (?, ?, ?)";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
for (User user : userList) {
ps.setString(1, user.getName()); // 自动处理 null 和转义
ps.setInt(2, user.getAge());
ps.setString(3, user.getEmail());
ps.addBatch(); // 加入批次,不立即执行
}
int[] results = ps.executeBatch(); // 一次性提交所有
System.out.println("成功插入 " + results.length + " 条");
}
</font>
<H3>提升性能的关键配置</H3>
<p>仅用 <code>addBatch()</code> 不够,还需数据库和 JDBC 驱动配合:</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill11083" title="Java调试"><img
src="https://img.php.cn/upload/skill/001/246/273/6adaf20dbae7c507.jpg" alt="Java调试" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill11083" title="Java调试">Java调试</a>
<p>通过 JDWP 实现 Java 远程调试:连接远程 JVM、设置断点、单步执行代码、查看变量值、获取调用栈。适用于需要调试远程 Java 应用、排查运行时状态、追踪代码执行流程的场景。
术语注解
JDWP:Java Debug Wire Protocol,Java 调试有线协议(Java 远程调试底层通信协议)
remote JVM:远程 Java 虚拟机
step through code:代码单步调试(步入 / 步过 / 步出调试)
inspect variables:变量查看 / 变量检视
stac</p>
</div>
<a href="/xiazai/skill11083" title="Java调试" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/c1c2c2ed740f" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">Java免费学习笔记(深入)</a>”;</p>
<ul>
<li>MySQL 连接 URL 加上 <code>rewriteBatchedStatements=true</code>(如 <code>jdbc:mysql://localhost:3306/db?rewriteBatchedStatements=true</code>),让驱动把多条 <code>INSERT</code> 合并为 <code>INSERT INTO t VALUES(...),(...),(...)</code> 形式</li>
<li>调用 <code>ps.executeBatch()</code> 前,可设 <code>conn.setAutoCommit(false)</code>,最后 <code>conn.commit()</code>,减少事务开销</li>
<li>每批控制在 500–2000 条(避免内存溢出或锁表太久),大列表记得分批处理</li>
</ul>
<H3>框架场景:MyBatis 批量插入</H3>
<p>若用 MyBatis,推荐 <code>foreach</code> 标签生成多值 INSERT(MySQL 支持):</p>
<font color="gray">
<pre class="brush:php;toolbar:false;">
<insert id="batchInsert">
INSERT INTO user(name, age, email) VALUES
<foreach collection="list" item="u" separator=",">
(#{u.name}, #{u.age}, #{u.email})
</foreach>
</insert>
注意:该写法依赖数据库是否支持多值插入(MySQL ✅,PostgreSQL 需 9.5+,Oracle ❌)。对不支持的库,MyBatis Plus 的 saveBatch() 或自定义分批循环仍是更稳妥选择。

















