mybatis使用foreach批次插入,解决sequence只查询一次的问题
2013-02-27 16:15
671 查看
oracle的批量插入方式是:
insert into db(id, zgbh, shbzh)
select '1', '2', '3' from dual
union all select '2', '3', '4' from dual
union all select '3', '4', '5' from dual
union all select '4', '5', '6' from dual
union all select '5', '6', '7' from dual
由于项目使用到sequence生成id,刚开始的写法:
<!-- 批次插入,List-->
<insert id="insertList" useGeneratedKeys="true" parameterType="java.util.List">
<selectKey resultType="long" keyProperty="id" order="BEFORE">
SELECT SEQ_xxx_DETAIL.NEXTVAL FROM DUAL
</selectKey>
insert into TBL_xxx_DETAIL
(
<include refid="allColumns"/>
)
<foreach collection="list" item="item" index="index" separator="UNION ALL" >
SELECT
#{id, jdbcType=NUMERIC javaType=long},
#{item.batchFundTitleId, jdbcType=NUMERIC javaType=long},
#{item.transactionRequestId, jdbcType=NUMERIC javaType=long},
#{item.arAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.bankServiceAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.receivedAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.realReceivedAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.verifyDate, jdbcType=DATE javaType=date},
#{item.verifyOp, jdbcType=VARCHAR javaType=string},
#{item.verifyStatus, jdbcType=INTEGER javaType=int},
#{item.created, jdbcType=VARCHAR javaType=string},
#{item.createdDate, jdbcType=DATE javaType=date},
#{item.createdIp, jdbcType=VARCHAR javaType=string},
#{item.modified, jdbcType=VARCHAR javaType=string},
#{item.modifiedDate, jdbcType=DATE javaType=date},
#{item.modifiedIp, jdbcType=VARCHAR javaType=string}
from dual
</foreach>
</insert>
这样的写法sequence的查询方法只查询一次,造成list中的对象的再插入时id都会一样,违反主键的唯一性约束。
所以修改为如下的形式:
<insert id="insertList" useGeneratedKeys="true" parameterType="java.util.List">
<selectKey resultType="long" keyProperty="id" order="BEFORE">
SELECT SEQ_xxx_DETAIL.NEXTVAL FROM DUAL
</selectKey>
insert into TBL_xxx_DETAIL
(
<include refid="allColumns"/>
) select SEQ_xxx_DETAIL.NEXTVAL,A.* from(
<foreach collection="list" item="item" index="index" separator="UNION ALL" >
SELECT
#{item.batchFundTitleId, jdbcType=NUMERIC javaType=long},
#{item.transactionRequestId, jdbcType=NUMERIC javaType=long},
#{item.arAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.bankServiceAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.receivedAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.realReceivedAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.verifyDate, jdbcType=DATE javaType=date},
#{item.verifyOp, jdbcType=VARCHAR javaType=string},
#{item.verifyStatus, jdbcType=INTEGER javaType=int},
#{item.created, jdbcType=VARCHAR javaType=string},
#{item.createdDate, jdbcType=DATE javaType=date},
#{item.createdIp, jdbcType=VARCHAR javaType=string},
#{item.modified, jdbcType=VARCHAR javaType=string},
#{item.modifiedDate, jdbcType=DATE javaType=date},
#{item.modifiedIp, jdbcType=VARCHAR javaType=string}
from dual
</foreach>) A
</insert>
把foreach中的id去掉,foreach拼出来的数据作为一张表A,然后从表A中查询数据,再接上从sequence中读取的值作为id。这样sequence的值就会多次读取,id就会不一样。
<selectKey resultType="long" keyProperty="id" order="BEFORE">
SELECT SEQ_xxx_DETAIL.NEXTVAL FROM DUAL
</selectKey>删除后会报错:SQL command not properly ended,暂时没有查出来原因,有知道的原因的请告诉我哈。
以此文抛砖引玉吧,希望能有更合适的方式。
mysql的批量插入如下:
INSERT INTO MyTable(ID,NAME) VALUES(7,'003'),(8,'004'),(9,'005')
而且mysql有自增字段,可以把id设置为自增的,这样的话就不存在id一致的情况。
<insert id="insertBatch" >
insert into student ( NAME,SEX,ADDRESS,TELEPHONE,TID)
values
<foreach collection="list" item="item" index="index" open="(" separator="," close=")">
#{item.name},
#{item.sex},
#{item.address},
#{item.telephone},
#{item.tId}
</foreach>
</insert
============================================================================================
create database link DBLinkName connect to 用户名 identified by 密码
using '(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.1)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)
)
)'
insert into db(id, zgbh, shbzh)
select '1', '2', '3' from dual
union all select '2', '3', '4' from dual
union all select '3', '4', '5' from dual
union all select '4', '5', '6' from dual
union all select '5', '6', '7' from dual
由于项目使用到sequence生成id,刚开始的写法:
<!-- 批次插入,List-->
<insert id="insertList" useGeneratedKeys="true" parameterType="java.util.List">
<selectKey resultType="long" keyProperty="id" order="BEFORE">
SELECT SEQ_xxx_DETAIL.NEXTVAL FROM DUAL
</selectKey>
insert into TBL_xxx_DETAIL
(
<include refid="allColumns"/>
)
<foreach collection="list" item="item" index="index" separator="UNION ALL" >
SELECT
#{id, jdbcType=NUMERIC javaType=long},
#{item.batchFundTitleId, jdbcType=NUMERIC javaType=long},
#{item.transactionRequestId, jdbcType=NUMERIC javaType=long},
#{item.arAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.bankServiceAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.receivedAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.realReceivedAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.verifyDate, jdbcType=DATE javaType=date},
#{item.verifyOp, jdbcType=VARCHAR javaType=string},
#{item.verifyStatus, jdbcType=INTEGER javaType=int},
#{item.created, jdbcType=VARCHAR javaType=string},
#{item.createdDate, jdbcType=DATE javaType=date},
#{item.createdIp, jdbcType=VARCHAR javaType=string},
#{item.modified, jdbcType=VARCHAR javaType=string},
#{item.modifiedDate, jdbcType=DATE javaType=date},
#{item.modifiedIp, jdbcType=VARCHAR javaType=string}
from dual
</foreach>
</insert>
这样的写法sequence的查询方法只查询一次,造成list中的对象的再插入时id都会一样,违反主键的唯一性约束。
所以修改为如下的形式:
<insert id="insertList" useGeneratedKeys="true" parameterType="java.util.List">
<selectKey resultType="long" keyProperty="id" order="BEFORE">
SELECT SEQ_xxx_DETAIL.NEXTVAL FROM DUAL
</selectKey>
insert into TBL_xxx_DETAIL
(
<include refid="allColumns"/>
) select SEQ_xxx_DETAIL.NEXTVAL,A.* from(
<foreach collection="list" item="item" index="index" separator="UNION ALL" >
SELECT
#{item.batchFundTitleId, jdbcType=NUMERIC javaType=long},
#{item.transactionRequestId, jdbcType=NUMERIC javaType=long},
#{item.arAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.bankServiceAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.receivedAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.realReceivedAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
#{item.verifyDate, jdbcType=DATE javaType=date},
#{item.verifyOp, jdbcType=VARCHAR javaType=string},
#{item.verifyStatus, jdbcType=INTEGER javaType=int},
#{item.created, jdbcType=VARCHAR javaType=string},
#{item.createdDate, jdbcType=DATE javaType=date},
#{item.createdIp, jdbcType=VARCHAR javaType=string},
#{item.modified, jdbcType=VARCHAR javaType=string},
#{item.modifiedDate, jdbcType=DATE javaType=date},
#{item.modifiedIp, jdbcType=VARCHAR javaType=string}
from dual
</foreach>) A
</insert>
把foreach中的id去掉,foreach拼出来的数据作为一张表A,然后从表A中查询数据,再接上从sequence中读取的值作为id。这样sequence的值就会多次读取,id就会不一样。
<selectKey resultType="long" keyProperty="id" order="BEFORE">
SELECT SEQ_xxx_DETAIL.NEXTVAL FROM DUAL
</selectKey>删除后会报错:SQL command not properly ended,暂时没有查出来原因,有知道的原因的请告诉我哈。
以此文抛砖引玉吧,希望能有更合适的方式。
mysql的批量插入如下:
INSERT INTO MyTable(ID,NAME) VALUES(7,'003'),(8,'004'),(9,'005')
而且mysql有自增字段,可以把id设置为自增的,这样的话就不存在id一致的情况。
<insert id="insertBatch" >
insert into student ( NAME,SEX,ADDRESS,TELEPHONE,TID)
values
<foreach collection="list" item="item" index="index" open="(" separator="," close=")">
#{item.name},
#{item.sex},
#{item.address},
#{item.telephone},
#{item.tId}
</foreach>
</insert
============================================================================================
create database link DBLinkName connect to 用户名 identified by 密码
using '(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.1)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)
)
)'
相关文章推荐
- mybatis使用foreach批次插入,解决sequence只查询一次的问题(在此,我只看union all 部分)
- 解决在mybatis中使用CTE进行oracle查询数据类型为long的字段出现流关闭问题
- 解决在mybatis中使用CTE进行oracle查询数据类型为long的字段出现流关闭问题
- MyBatis使用foreach进行批量插入遇到的问题以及解决方法
- 解决mybatis使用char类型字段查询oracle数据库时结果返回null问题
- mybatis不能插入,查询中文的问题以及可能的解决办法,以及Mysql数据库编码的设置
- "执行SQL语句时出现问题操作必须使用一个可更新的查询"错误的解决方法
- 在动态插入Easyui datebox控件时,使用$.parser.parse()手工渲染时,解决日期控件原有的值被清除问题
- mybatis在使用insert into 批量插入数据的问题
- 使用mybatis遇到的关于条件查询">"以及if test传参的使用问题
- 解决mysqldb查询大量数据导致内存使用过高的问题
- Android:关于Android Studio连接手机的各种问题 & 解决“通常每个套接字地址(协议/网络地址/端口)只允许使用一次(10048)”的问题。
- Oracle数据库批量插入使用Sequence.nextval报错ORA:02287问题解决
- mysql中insert与select的嵌套使用解决组合字段插入问题
- 使用MyBatis查询 返回类型为int,但是当查询结果为空NULL,报异常的解决方法
- solr查询不使用query analyzer中文分词的问题解决
- 解决绕过android下apk使用usb设备权限查询相应问题,自动获取usb权限
- 解决使用robot framework + selenium测试时,RIDE运行一次后不显示log的问题
- 使用JRockit作为工具检测并解决JAVA内存泄漏问题的一次实战
- 解决"操作必须使用一个可更新的查询"问题