mybatis批量插入数据到oracle出错

本文介绍使用MyBatis在Oracle数据库中实现批量插入的方法,针对原有SQL语法问题进行了修正,采用UNION ALL方式成功实现了多条记录的同时插入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在程序中封装一个List集合对象,然后把该集合中的实体插入到数据库中,因为项目使用了MyBatis,所以打算使用MyBatis的foreach功能进行批量插入。期间遇到了“SQL 命令未正确结束 ”的错误,最终解决,记录下来供以后查阅和学习。

之前写的:

<insert id="addInvoiceDetailList" parameterType="java.util.List">
        insert into WC_PURCHASE_INVOICE_D (invoiceid,itemname,purchaseno,costid,typeid,typename,spec,weight,price,amountnotax,taxrate,taxvalue,amounttax,creator,updateby,updatetime,handcode)   
	    values  
	    <foreach collection="list" item="item" index="index" separator="," >  
	    (	#{item.invoiceid,jdbcType=VARCHAR},
	        #{item.itemname,jdbcType=VARCHAR},
	        #{item.purchaseno,jdbcType=VARCHAR},
			#{item.costid,jdbcType=VARCHAR},
			#{item.typeid,jdbcType=VARCHAR},
			#{item.typename,jdbcType=VARCHAR},
			#{item.spec,jdbcType=VARCHAR},
			#{item.weight,jdbcType=DOUBLE},
			#{item.price,jdbcType=DOUBLE},
			#{item.amountnotax,jdbcType=DOUBLE},
			#{item.taxrate,jdbcType=DOUBLE},
			#{item.taxvalue,jdbcType=DOUBLE},
			#{item.amounttax,jdbcType=DOUBLE},
			#{item.creator,jdbcType=VARCHAR},
			#{item.updateby,jdbcType=VARCHAR},
			sysdate,
			#{item.handcode,jdbcType=VARCHAR}

	    )  
	    </foreach>  
    </insert>


这条sql插入一条时没报错,但是插入多条的时候就会报错(ORA-00933: SQL 命令未正确结束),

把SQL复制出来在PL/SQL中运行也是报同样的错,如上也可以看出,使用批量插入执行的SQL语句等价于: INSERT INTO xxx(xx,xx) VALUES (?,?),(?,?),而在oracle中用insert into xxx values (xxx,xxx),(xxx,xxx) 这种语法是通不过的 。查了资料之后发现这是适用于MySQL的,不适用于Oracle,因此把xml文件修改一下:

<insert id="addInvoiceDetailList" parameterType="java.util.List">
        insert into WC_INVOICE_D (invoiceid,itemname,purchaseno,costid,typeid,typename,spec,weight,price,amountnotax,taxrate,taxvalue,amounttax,creator,updateby,updatetime,handcode)   
	    <foreach collection="list" item="item" index="index" separator="UNION ALL">  
	    select
	    	#{item.invoiceid,jdbcType=VARCHAR},
	        #{item.itemname,jdbcType=VARCHAR},
	        #{item.purchaseno,jdbcType=VARCHAR},
		#{item.costid,jdbcType=VARCHAR},
		#{item.typeid,jdbcType=VARCHAR},
		#{item.typename,jdbcType=VARCHAR},
		#{item.spec,jdbcType=VARCHAR},
		#{item.weight,jdbcType=DOUBLE},
		#{item.price,jdbcType=DOUBLE},
		#{item.amountnotax,jdbcType=DOUBLE},
		#{item.taxrate,jdbcType=DOUBLE},
		#{item.taxvalue,jdbcType=DOUBLE},
		#{item.amounttax,jdbcType=DOUBLE},
		#{item.creator,jdbcType=VARCHAR},
		#{item.updateby,jdbcType=VARCHAR},
		sysdate,
		#{item.handcode,jdbcType=VARCHAR}
	    from dual 
	    </foreach>  
    </insert>

运行通过。

在Oracle的版本中,有几点需要注意的:

1.SQL中没有VALUES;

2.<foreach>标签中的(selece ..... from dual);

3.<foreach>标签中的separator的属性为"UNION ALL",将查询合并结果集。



MyBatis-Plus 是在 MyBatis 基础上进行的增强工具,旨在简化开发、提高效率。两者都用于 Java 应用程序中的持久层操作,但它们在功能和使用方式上有显著区别。 ### 功能与特性对比 1. **CRUD 操作简化** MyBatis 需要手动编写 SQL 语句并在 XML 文件或注解中配置映射关系,开发者需要为每个表编写对应的增删改查方法。而 MyBatis-Plus 提供了通用的 `BaseMapper` 接口,内置了常见的 CRUD 方法,几乎不需要编写额外的 SQL 即可完成基础数据操作。例如: ```java public interface UserMapper extends BaseMapper<User> { } ``` 这种方式极大减少了样板代码,并提高了开发效率[^2]。 2. **自动填充功能** MyBatis-Plus 支持字段自动填充功能(如创建时间和更新时间),通过实现 `MetaObjectHandler` 接口即可定义自动填充逻辑。这种方式避免了在每次插入或更新时都需要手动设置这些字段值的情况。相比之下,MyBatis 需要自行处理这些字段的赋值逻辑。 3. **分页查询支持** 在 MyBatis 中实现分页通常需要借助插件或者自定义 SQL,而 MyBatis-Plus 内置了强大的分页插件 `PaginationInterceptor`,只需简单配置即可轻松实现分页功能。例如: ```java Page<User> page = new Page<>(1, 10); userMapper.selectPage(page, null); ``` 4. **条件构造器** MyBatis-Plus 引入了 `QueryWrapper` 和 `UpdateWrapper` 等条件构造器,使得构建动态查询条件更加直观且类型安全。例如: ```java List<User> users = userMapper.selectList(new QueryWrapper<User>().eq("age", 30)); ``` 而在 MyBatis 中,虽然可以通过 `<if>` 标签实现类似功能,但其语法较为繁琐且容易出错。 5. **性能优化与扩展性** MyBatis-Plus 提供了一些性能优化的功能,比如批量插入 (`insertBatchSomeColumn`) 和乐观锁机制等。此外,它还支持多种数据库方言以及与 ShardingSphere 等分库分表中间件的集成,进一步提升了系统的可扩展性和灵活性[^1]。 6. **分布式全局唯一 ID 生成** MyBatis-Plus 可以方便地集成百度 UIDGenerator 或 Snowflake 算法来生成分布式环境下的唯一主键。这种能力对于微服务架构尤为重要,因为它确保了跨节点的数据一致性。而在 MyBatis 中,这类需求通常需要额外引入第三方库或自行实现。 7. **事务管理** 对于复杂的业务场景,MyBatis-Plus 同样能够很好地支持声明式事务管理,并且可以结合 XA 事务协议实现跨库事务控制。例如: ```java @Transactional(rollbackFor = Exception.class) public void batchAdd() { TransactionTypeHolder.set(TransactionType.XA); // 插入订单及订单项... } ``` 此外,它还可以与其他框架(如 Spring)无缝协作,提供更高级别的事务抽象[^3]。 8. **SQL 兼容性与迁移支持** 当从 MySQL 迁移到 Oracle 时,MyBatis-Plus 提供了一定程度上的 SQL 语法兼容性转换支持,帮助减少因底层数据库变更带来的工作量。例如,在 Oracle 中计算两个日期之间的差异可以直接使用 ROUND 函数配合 TO_DATE 实现,而无需修改大量现有代码[^4]。 9. **易用性与社区生态** MyBatis-Plus 拥有活跃的中文社区和支持文档,适合国内开发者快速上手;同时,它也提供了丰富的示例项目和最佳实践指南。这使得即使是初学者也能迅速掌握其核心功能并应用于实际项目中。 综上所述,尽管 MyBatis 作为一款经典的 ORM 框架依然具有广泛的适用范围,但 MyBatis-Plus 以其简洁的设计理念、高效的开发模式以及对现代应用场景的良好适配能力,在许多方面超越了原生 MyBatis。特别是在大型分布式系统中,MyBatis-Plus 的优势更为明显。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值