mybatis批量操作-oracle版

73 阅读2分钟

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>

这个语句执行后会报如下错误:

image.png 明显是缺少了 一个 分号 ; 那如果在语句后面加上行不行?我可以肯定告诉你,不行

错误示例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数据库的表,然后再做修改。

总结:

  1. 使用mybatis时,非批量操作的SQL,所有数据库都是通用的
  2. 如果使用批量操作,需要根据数据库不同做不同调整,因为语法不一样
  3. 实在不行,直接找大佬改源码吧,就改解析XML拼接SQL那里 😁