MySQL支持的语法

INSERT INTO `tableX` (
`a`,
`b`,
`c`,
`d`,
`e`
) VALUES
<foreach collection ="list" item="param" index= "index" separator =",">
(
param.a,
param.b,
param.c,
param.d,
param.e
)
</foreach>

oracle语法

insert into tableX
(a,b,c)
select * from (
select 1,2,3 from dual
union
select 4,5,6 from dual
) t

在使用mybatis时,oracle需要写成下面格式

<foreach collection="list" item="file" index="index" separator="UNION">

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

首先,在网上参考了有关Mybatis的foreach insert的资料,具体如下:

foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。

foreach元素的属性主要有 item,index,collection,open,separator,close。

item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况 下,该属性的值是不一样的,主要有一下3种情况:

1.如果传入的是单参数且参数类型是一个List的时候,collection属性值为list

2.如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array

3.如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map

然后,照葫芦画瓢写了如下的xml文件,

xxxMapper.xml文件:

<insert id="addSupCity" parameterType="java.util.List">
    <selectKey keyProperty="cityId" order="BEFORE" resultType="String">
        <![CDATA[SELECT SEQ_OCL_SUPCITY.NEXTVAL FROM dual]]>
    </selectKey>
    INSERT INTO T_OCL_SUPCITY
    (CITY_ID,CITY_CODE, CITY_NAME, AREA_DESC, SUP_ID, STAT)
    VALUES
<foreach collection="list" item="item" index="index" separator=",">
(
        #{item.cityId,jdbcType=VARCHAR},
        #{item.cityCode,jdbcType=VARCHAR},
        #{item.cityName,jdbcType=VARCHAR},
        #{item.areaDesc,jdbcType=VARCHAR},
        #{item.supId,jdbcType=VARCHAR},
        #{item.stat,jdbcType=VARCHAR}
)
</foreach>
</insert>

但是运行起来后就一直报错,报错信息如下:

### SQL: INSERT INTO T_OCL_SUPCITY
(CITY_ID,CITY_CODE, CITY_NAME, AREA_DESC, SUP_ID, STAT) VALUES (?,?,?,?,?),(?,?,?,?,?)
### Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正确结束

把SQL复制出来在PL/SQL中运行也是报同样的错,如上也可以看出,使用批量插入执行的SQL语句等价于: INSERT INTO T_OCL_SUPCITY (CITY_ID,CITY_CODE, CITY_NAME, AREA_DESC, SUP_ID, STAT) VALUES (?,?,?,?,?),(?,?,?,?,?),而在oracle中用insert into xxx values (xxx,xxx),(xxx,xxx) 这种语法是通不过的 。再回过头去看那篇文章,发现这是适用于MySQL的,不适用于Oracle,因此把xml文件修改一下:

<insert id="addSupCity" parameterType="java.util.List">
INSERT INTO T_OCL_SUPCITY
(CITY_ID,CITY_CODE, CITY_NAME, AREA_DESC, SUP_ID, STAT)
SELECT SEQ_OCL_SUPCITY.NEXTVAL CITY_ID, A.*
FROM(
<foreach collection="list" item="item" index="index" separator="UNION ALL">
SELECT
#{item.cityCode,jdbcType=VARCHAR} CITY_CODE,
#{item.cityName,jdbcType=VARCHAR} CITY_NAME,
#{item.areaDesc,jdbcType=VARCHAR} AREA_DESC,
#{item.supId,jdbcType=VARCHAR} SUP_ID,
#{item.stat,jdbcType=VARCHAR} STAT
FROM dual
</foreach>
)A
</insert>

运行通过。在Oracle的版本中,有几点需要注意的:

1.SQL中没有VALUES;

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

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

Mybatis对oracle数据库进行foreach批量插入操作的更多相关文章

  1. Mybatis 针对ORACLE和MYSQL的批量插入与多参数批量删除

    今天利用Mybatis的<for each>标签做oracle的批量插入数据时,发现和MySQL数据库有区别.在此记录下,以防之后再踩坑. 一.批量插入: 1.controller: /* ...

  2. mybatis foreach批量插入数据:Oracle与MySQL区别

    mybatis foreach批量插入数据:Oracle与MySQL不同点: 主要不同点在于foreach标签内separator属性的设置问题: separator设置为","分 ...

  3. 使用mybatis向oracle数据库插入数据异常

    遇到了使用mybatis向oracle数据库插入数据异常的问题, 具体的报错如下:org.springframework.jdbc.UncategorizedSQLException: ### Err ...

  4. mybatis oracle两种方式批量插入数据

    mybatis oracle两种方式批量插入数据 注意insert,一定要添加: useGeneratedKeys="false" ,否者会报错. <insert id=&q ...

  5. MyBatis 使用 foreach 批量插入

    MyBatis 使用 foreach 批量插入 参考博文 老司机学习MyBatis之动态SQL使用foreach在MySQL中批量插入 使用MyBatis一次性插入多条数据时候可以使用 <for ...

  6. MyBatis 学习笔记(七)批量插入ExecutorType.BATCH效率对比

    MyBatis 学习笔记(七)批量插入ExecutorType.BATCH效率对比一.在mybatis中ExecutorType的使用1.Mybatis内置的ExecutorType有3种,默认的是s ...

  7. Java豆瓣电影爬虫——减少与数据库交互实现批量插入

    节前一个误操作把mysql中record表和movie表都清空了,显然我是没有做什么mysql备份的.所以,索性我把所有的表数据都清空的,一夜回到解放前…… 项目地址:https://github.c ...

  8. oracle数据库表中,插入数据的时候如何产生一个 字母+数字 编号?

    Oracle 语句中“||”代表什么啊? oracle数据库表中,插入数据的时候如何产生一个 字母+数字 编号? 排序的话,用order by来处理即可.比如:cola123a234b999b335s ...

  9. JDBC的批量插入操作

    在今天之前,当我遇到需要使用JDBC对数据库进行批量插入操作的时候,我使用的方法如下: ①使用Connection建立数据库连接: ②使用PreparedStatement提交SQL语句,将数据插入: ...

随机推荐

  1. .NetCore使用Swagger进行单版本或多版本控制处理

    前面已经介绍过了Swagger的基础使用了 下面继续分别详细说明下 不添加版本控制以及添加版本控制的使用情况,其实也基本一致,对看起来可能更加容易理解 第一步 导入nuget包 nuget导入Swas ...

  2. elasticflow

    https://github.com/robcowart/elastiflow/blob/master/INSTALL.md

  3. 【Java】 大话数据结构(1) 线性表之顺序存储结构

     本文根据<大话数据结构>一书,实现了Java版的顺序存储结构. 顺序存储结构指的是用一段地址连续的存储单元一次存储线性表的数据元素,一般用一维数组来实现. 书中的线性表抽象数据类型定义如 ...

  4. 大数据技术之_14_Oozie学习_Oozie 的简介+Oozie 的功能模块介绍+Oozie 的部署+Oozie 的使用案列

    第1章 Oozie 的简介第2章 Oozie 的功能模块介绍2.1 模块2.2 常用节点第3章 Oozie 的部署3.1 部署 Hadoop(CDH版本的)3.1.1 解压缩 CDH 版本的 hado ...

  5. oracle 查询 约束

    select * FROM all_constraints where CONSTRAINT_NAME='SYS_xxx'

  6. strlen()和mb_strlen()

    换行需要用双引号,单引号只会输出字符. strlen()返回字符串所占的字节数,对于utf8编码的中文,一个汉字占三个字节. mb_strlen()返回字符个数,如果不写第二个参数,就会使用内部编码, ...

  7. U盘制作Win7安装盘的方法

    Windows 7 USB/DVD download tool 微软官方说明:http://www.microsoftstore.com/st ... Win7_usbdvd_dwnTool 下载地址 ...

  8. MySQL分析数据运行状态【SHOW PROCESSLIST】

    这个博文,将只是简单的记录一下,我们的数据库操作和使用中,加索引加不上去,分析的过程,其实比较简单,就是看有没有连接进程还在操作表.有的话,将其停掉(不影响业务的场景下). 今天的主角是: SHOW ...

  9. HDU 3970 Paint Chain (博弈,SG函数)

    Paint Chain Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  10. 打印函数 lodop

    Lodop属性和方法详解 例子:LODOP.PRINT_INIT("打印任务名");LODOP.SET_PRINT_COPIES(2);bdhtml=window.document ...