oracle mybatis批量插入报sql语句过长

现象:在做读者信息导入的时候,导入的读者信息量有点大,结果sql报错,错误原因是执行的sql语句太长了。

原因:经断点跟踪代码,发现底层mybati xml中插入读者信息方法是个批量插入,采用union all 把所有的insert语句拼接成一个语句,然而因为导入的读者信息数据量过大,导致拼接的sql语句长度超过了6000个字符,导致报错。以下是网上查询资料结果:

clipboard.png

mybatis-oracle批量插入问题:

clipboard.png

如上图所示:如果插入的数据量很大,union all后,sql语句都会非常的长,数据量小,不会报错,数据量大了,sql很长,超过最大可执行长度都会报错。错误如下图所示:

clipboard.png

解决办法:

1.改为一条一条的插入(不推荐使用)

2.改为用 insert into( ***) select ** from xx(推荐使用)

PS:如果一个执行sq大小都都有几十kb甚至几M,那都要好好检查一下sql写得是否有问题

### MyBatisOracle 11g 批量插入 SQL 实现方法 在 MyBatis 中实现 Oracle 数据库的批量插入操作时,需遵循特定的 SQL 语法结构。由于 Oracle 不支持 `INSERT INTO ... VALUES (...)` 的批量形式,因此通常采用基于 `SELECT FROM DUAL` 结合 `UNION ALL` 的方式完成。 以下是适用于 Oracle 11g 的批量插入 SQL 示例: #### XML 配置文件中的实现 ```xml <insert id="batchInsert" parameterType="java.util.List"> INSERT INTO TABLE_NAME (ID, NAME) SELECT #{item.id}, #{item.name} FROM dual <foreach collection="list" item="item" separator=" UNION ALL "> SELECT #{item.id}, #{item.name} FROM dual </foreach> </insert> ``` 在此配置中: - 使用 `<foreach>` 标签遍历传入的参数列表。 - 每次迭代生成一个 `SELECT ... FROM DUAL` 子查询,并通过 `UNION ALL` 连接多个子查询[^2]。 - 参数 `${}` 或 `#{}` 均可用于绑定动态值,但建议优先使用 `#{}` 来防止 SQL 注入风险。 #### Java 调用代码示例 假设实体类定义如下: ```java public class User { private Integer id; private String name; // Getter and Setter methods... } ``` 调用批量插入的方法可以这样编写: ```java List<User> userList = new ArrayList<>(); userList.add(new User(1, "张三")); userList.add(new User(2, "李四")); int result = sqlSession.insert("namespace.batchInsert", userList); sqlSession.commit(); System.out.println("受影响行数:" + result); ``` 此代码片段展示了如何将一组对象传递给 MyBatis 并执行批量插入操作。 --- ### 关键注意事项 1. **性能优化** 推荐使用单条 SQL 完成所有记录的插入,而非多次单独执行 `INSERT` 语句。后者不仅效率低下,还可能引发事务管理上的复杂性[^2]。 2. **序列处理** 如果目标表的主键依赖于 Oracle 序列,则可以在插入前预先获取序列值并赋值给对应字段。例如: ```sql SELECT sequence_name.NEXTVAL AS id FROM dual ``` 3. **XML 转义字符** 在 MyBatis 的 XML 文件中,特殊字符(如 `<`, `>`, `&` 等)需要转义为对应的 HTML 实体编码[^3]。例如: - `<` 替换为 `<` - `>` 替换为 `>` - `&` 替换为 `&` --- ### 总结 上述方法利用了 Oracle 支持的 `DUAL` 表特性以及 MyBatis 提供的 `<foreach>` 功能,实现了高效的批量插入逻辑。这种方法既满足功能需求又兼顾了性能考虑。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值