举个例子:
现在要批量新增User对象到数据库USER表中
public class User{ //姓名 private String name; //年龄 private Integer age; //性别 private Integer sex }
大部分人对MySQL比较熟悉,可能觉得批量新增的SQL都是这样写,其实并不然。该写法在MySQL中没问题,而在Oracle中,这样写就会报错。
MySQL写法:
INSERT INTO USER (NAME,AGE,SEX) VALUES ('val1_1', 'val1_2', 'val1_3'), ('val2_1', 'val2_2', 'val2_3'), ('val3_1', 'val3_2', 'val3_3');
Oracle写法:
//多次单条插入 INSERT INTO USER (NAME,AGE,SEX) VALUES ('val1_1', 'val1_2', 'val1_3'); INSERT INTO USER (NAME,AGE,SEX) VALUES ('val2_1', 'val2_2', 'val2_3'); INSERT INTO USER (NAME,AGE,SEX) VALUES ('val3_1', 'val3_2', 'val3_3'); //批量插入 INSERT ALL INTO USER (NAME,AGE,SEX) VALUES ('val1_1', 'val1_2', 'val1_3') INTO USER (NAME,AGE,SEX) VALUES ('val2_1', 'val2_2', 'val2_3') INTO USER (NAME,AGE,SEX) VALUES ('val3_1', 'val3_2', 'val3_3') SELECT 1 FROM DUAL;
可以发现Oracle的两种写法都比较的麻烦,批量插入也压根没有减少插入的列名。除此之外,另一个麻烦的事情就是,在企业开发中,一套软件系统可能需要支持多套数据库的,因此这条新增的操作,就得适配两套数据库,维护两套SQL,大大地增加了开发成本。
那么有没有一种通用的写法呢?答案是有的。
通用写法:
INSERT INTO USER (NAME,AGE,SEX) select ('val1_1', 'val1_2', 'val1_3') from dual union all select ('val2_1', 'val2_2', 'val2_3') from dual union all select ('val3_1', 'val3_2', 'val3_3') from dual
这样一来,既简单又能少维护一套SQL,两全其美。
下面是XML文件里各种写法的代码。
<insert id="batchInsertUser" databaseId="mysql"> INSERT INTO USER (NAME,AGE,SEX) VALUES <foreach collection="userList" index="index" item="user" separator=","> (#{user.name},#{user.age},#{user.sex}) foreach> insert>
<insert id="batchInsertUser" databaseId="oracle"> BEGIN <foreach collection="userList" index="index" item="user" separator=";"> INSERT INTO USER (NAME,AGE,SEX) VALUES (#{user.name},#{user.age},#{user.sex}) foreach> ;END; insert>
仔细观察MySQL和Oracle的写法,因为MySQL支持上述在VALUES后面直接插入多条数据,因此。foreach
标签只需要循环遍历出VALUES后面()
里的内容即可;而Oracle因为不支持这种写法因此需要循环遍历整个INSERT语句。
<insert id="batchInsertUser" databaseId="mysql"> INSERT INTO USER (NAME,AGE,SEX) <foreach collection="userList" index="index" item="user" separator="union all"> SELECT (#{user.name},#{user.age},#{user.sex}) FROM DUAL foreach> insert>