1 简介
虽然SQL对所有DB都是通用的,但是oracle和MySQL的存储还是有一些不一样的。基础是通用,比如说一条条的CRUD操作数据。但批量操作就不是通用的了,每个数据库自己的规则不一样,所以在XML写的批量SQL语句也是不一样的。下面主要讲oracle的操作
/**
* mysql的批量操作语法
*/
INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...), (value1, value2, value3, ...), (value1, value2, value3, ...), ...
/**
* oracle的批量操作语法
*/
INSERT ALL INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...) INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...) INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...) SELECT 1 FROM DUAL
2 批量插入
oracle的批量插入示例
insert into PERSON(USER_NAME,AGE)
<foreach collection="pos" item="po" separator="union all">
<if test="po != null">
select
#{po.userName} as USER_NAME,
#{po.age} as AGE
from dual
</if>
</foreach>
3 批量修改
oracle的批量修改有一些不一样
错误示例1
<foreach collection="pos" item="po" index="index" separator=";">
UPDATE person set age = 1 where id = 1
</foreach>
这个语句执行后会报如下错误:
明显是缺少了 一个 分号 ;
那如果在语句后面加上行不行?我可以肯定告诉你,不行
错误示例2
换一种写法:使用CDATA,关于CDATA的用法和作用,大家自行百度。
begin
<foreach collection="pos" item="po" index="index" separator=";">
UPDATE person set age = 1 where age = 1
</foreach>
; end <![CDATA[;]]>
这个语句是把执行命令管理在一个事务里,然后统一执行,但是结果还是不行,报错和上面的报错一样。原因和上面的一样,mybatis会在解析XML拼接SQL后擦除最后的分号,就算使用了CDATA做限制也不行
那是不是我只能修改源码才能把分号补上? 修改源码只有在没办法时候才做,不是不能改,是时间不允许,正常开发没时间去改源码这东西。
正确示例3:
在oracle中,其实有一些区别于通用SQL的写法,使用这种写法是可以做到批量修改的
MERGE INTO PERSON p1
USING (
<foreach collection="pos" item="po" index="index" separator="union">
select
#{po.id,jdbcType=VARCHAR} id,
#{po.name,jdbcType=NUMERIC} name
from dual
</foreach>
) p2
ON (
p1.id = p2.id
)
WHEN MATCHED THEN
UPDATE SET p1.name = p2.name
p2 是一张虚拟表,把内存变量写入p2,然后通过条件关联p1数据库的表,然后再做修改。
总结:
- 使用mybatis时,非批量操作的SQL,所有数据库都是通用的
- 如果使用批量操作,需要根据数据库不同做不同调整,因为语法不一样
- 实在不行,直接找大佬改源码吧,就改解析XML拼接SQL那里 😁