Mybatis对oracle数据库进行foreach批量插入操作
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批量插入操作的更多相关文章
- Mybatis 针对ORACLE和MYSQL的批量插入与多参数批量删除
今天利用Mybatis的<for each>标签做oracle的批量插入数据时,发现和MySQL数据库有区别.在此记录下,以防之后再踩坑. 一.批量插入: 1.controller: /* ...
- mybatis foreach批量插入数据:Oracle与MySQL区别
mybatis foreach批量插入数据:Oracle与MySQL不同点: 主要不同点在于foreach标签内separator属性的设置问题: separator设置为","分 ...
- 使用mybatis向oracle数据库插入数据异常
遇到了使用mybatis向oracle数据库插入数据异常的问题, 具体的报错如下:org.springframework.jdbc.UncategorizedSQLException: ### Err ...
- mybatis oracle两种方式批量插入数据
mybatis oracle两种方式批量插入数据 注意insert,一定要添加: useGeneratedKeys="false" ,否者会报错. <insert id=&q ...
- MyBatis 使用 foreach 批量插入
MyBatis 使用 foreach 批量插入 参考博文 老司机学习MyBatis之动态SQL使用foreach在MySQL中批量插入 使用MyBatis一次性插入多条数据时候可以使用 <for ...
- MyBatis 学习笔记(七)批量插入ExecutorType.BATCH效率对比
MyBatis 学习笔记(七)批量插入ExecutorType.BATCH效率对比一.在mybatis中ExecutorType的使用1.Mybatis内置的ExecutorType有3种,默认的是s ...
- Java豆瓣电影爬虫——减少与数据库交互实现批量插入
节前一个误操作把mysql中record表和movie表都清空了,显然我是没有做什么mysql备份的.所以,索性我把所有的表数据都清空的,一夜回到解放前…… 项目地址:https://github.c ...
- oracle数据库表中,插入数据的时候如何产生一个 字母+数字 编号?
Oracle 语句中“||”代表什么啊? oracle数据库表中,插入数据的时候如何产生一个 字母+数字 编号? 排序的话,用order by来处理即可.比如:cola123a234b999b335s ...
- JDBC的批量插入操作
在今天之前,当我遇到需要使用JDBC对数据库进行批量插入操作的时候,我使用的方法如下: ①使用Connection建立数据库连接: ②使用PreparedStatement提交SQL语句,将数据插入: ...
随机推荐
- java Comparator和Comparable(比较器)
Comparable: 一个类实现了Camparable接口则表明这个类的对象之间是可以相互比较的,这个类对象组成的集合就可以直接使用sort方法排序,sort方法调用compareTo()方法里定义 ...
- java 内部类 工厂方法
用内部类实现工厂模式 :优先使用类而不是接口,如果你的设计中需要某个接口,你必须了解它,否则不到迫不得已,不要将其放到你的类中 //: innerclasses/Factories.java impo ...
- PLSQL Developer连接远程oracle配置
在windows机器上不想安装oracle或者oracle的客户端,我们怎么使用PLSQL Developer工具呢?答案如下: 环境 windows7 ...
- MySql 时间戳存char还是存int?
一次小事故,让我对时间戳存char还是存int有了深刻的印象. 生产环境的sql条件涉及到时间戳字段的大小比较(between and),当时设计的时间戳类型是char(10),结果当数据量达到200 ...
- [mysql] update……from……
今天插入一条数据就像这样 limit ), , )) 然后报错: You can't specify target table 'categorys' for update in FROM claus ...
- vue-video-player的使用总结
由于公司的项目是网上教育的,像网易云课堂那种教育网站,因而会有很多课程需要在线观看的,所以视频插件是必不可少的. 由于我用vue开发项目,所以找视频插件也找和vue贴近的.最后选择了vue-video ...
- 【BZOJ 4832 】 4832: [Lydsy2017年4月月赛]抵制克苏恩 (期望DP)
4832: [Lydsy2017年4月月赛]抵制克苏恩 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 275 Solved: 87 Descripti ...
- BZOJ.4939.[Ynoi2016]掉进兔子洞(莫队 bitset 分组询问)
BZOJ 洛谷 删掉的数即三个区间数的并,想到bitset:查多个区间的数,想到莫队. 考虑bitset的每一位如何对应每个数的不同出现次数.只要离散化后不去重,每次记录time就可以了. 但是如果对 ...
- poj 3368 rmq ***
题意:给出n个数和Q个询问(l,r),对于每个询问求出(l,r)之间连续出现次数最多的次数. #include<cstdio> #include<iostream> #incl ...
- 【BZOJ-3730】震波 动态点分治 + 树状数组
3730: 震波 Time Limit: 15 Sec Memory Limit: 256 MBSubmit: 626 Solved: 149[Submit][Status][Discuss] D ...