Mybatis+Oracle进行数据的批量插入和更新

项目中会遇到这样的情况,查询出多条记录(一个List对象集合),一次性要插入多条数据到数据库中,下面就拿Data类来看看两种插入方法:

方法一:

  Mybatis本身只支持逐条插入,比较笨的方法,就是遍历一个List,循环中逐条插入,比如下面这段代码

<pre class="java" style="margin-top: 0px; margin-bottom: 10px; box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, ‘Courier New‘, monospace; font-size: 13px; padding: 9.5px; color: rgb(51, 51, 51); word-break: break-all; word-wrap: break-word; border: 1px solid rgb(204, 204, 204); border-radius: 4px; background-color: rgb(245, 245, 245);">for(Data d : ListData) {
dataMapper.insertSelective(d);
}  

这样做的后果就是效率严重低下,因为每次循环都要向数据库提交一次,数据少的时候看不出来,但是如果上千条,花费的时间就相当多了;

方法二:

  Mybatis本身是很灵活的,因为可以自己在XML文件中编写sql进行操作,那就可以一次性将插入到数据库中,这样只用向数据库提交一次,性能也可以提高不少。此处需要注意,对于不同数据库,mapper.xml里的配置方式不一样,我用的是Oracleoracle批量插入记录的书写方式跟sqlServer,MySQL的不一样,下面来看一个Oracle例子:

 首先,在DataMapper.Java 接口类中加入接口:

int batchInsert(List<Data> datas);  

然后,在xxxMapper.xml 中编写对应的实现sql,我使用的是oracle,如果是mysql或sqlserver,可能sql语句会略有区别吧:

<insert id="batchInsert"parameterType="java.util.List">
 insert into DATA (ID, TEXT, STAUTS)
 <foreach close=")"collection="list"item="item"index="index"open="("separator="union">
select
#{item.id,jdbcType=VARCHAR},
#{item.text,jdbcType=VARCHAR},
#{item.stauts,jdbcType=VARCHAR}
 from dual
</foreach>
</insert>  

说明一下xml文件的实现,使用foreach标签,是用来拼接内部的字符串,item就相当于一个指针,用来遍历list中的对象,将每一个item的属性值复制给内部sql之后,用union拼接起来,一次性执行一个长的sql语句。   如果我们从后台打印sql执行语句的话,会看到这样的sql语句

insert into DATA (ID, TEXT, STAUTS)
(
select ?, ?, ? from dual union
select ?, ?, ? from dual union
select ?, ?, ? from dual
) 

相对于第一个方法,第二个方法的代码量要多出很多,但是从性能方面考虑,不管插入多少条数据,都只用向数据库提交一次,这样效率就会大幅提升。

时间: 2024-10-18 14:42:09

Mybatis+Oracle进行数据的批量插入和更新的相关文章

C#使用SqlDataAdapter 实现数据的批量插入和更新

近日由于项目要求在需要实现中型数据的批量插入和更新,晚上无聊,在网上看到看到这样的一个实现方法,特摘抄过来,以便以后可能用到参考. 一.数据的插入 DateTime begin = DateTime.Now; string connectionString = ......; using(SqlConnection conn = new SqlConnection(connectionString)){ conn.Open(); SqlDataAdapter sd = new SqlDataAd

Hibernate批处理操作优化 (批量插入、更新与删除)

问题描述 我开发的网站加了个新功能:需要在线上处理表数据的批量合并和更新,昨天下午发布上线,执行该功能后,服务器的load突然增高,变化曲线异常,SA教育了我一番,让我尽快处理,将CPU负载降低. 工作所需,我经常要写些程序批量处理数据,每次执行几十万数据处理的时候,我机子的CPU都会飙高,而且数据处理速度会越来越慢.比如第一个1W条要5分钟,第二个1W条就要10分钟,要干其他事情的时候机子也卡的不行,只能等着处理完数据. 其实我一直认为是数据量太大,从来不认为是程序问题,所以一直没怎么关注过.

Asp.net QueryString批量插入和更新

public static string InsertOrUpdateQueryString(string[] keys, string[] values) { return InsertOrUpdateQueryString(System.Web.HttpContext.Current.Request, keys, values); } public static string InsertOrUpdateQueryString(System.Web.HttpRequest request,

java批量插入或更新的问题

在批量插入或者更新中,setXXX的时候字段类型必须一致.例如:在普通sql中 pstmt8.setBigDecimal(j ,xxx);可以写成pstmt8.setString(j,xxx.toString()); 但在批量插入时必须写成pstmt8.setBigDecimal(j,xxx);否则批处理会报提交中至少有一条不成功的问题.折腾一下午,终于搞好了.顺便记下来,方便参考.

oracle——数据表的相关操作——插入数据以及批量插入数据

SQL更新数据 1.插入数据——insert操作 语法格式如下: insert into 表名 (列名1,列名2……,列名n) values (值1,值2……,值n); 在insert操作中,列名列表中的各列需要以逗号分隔:而值列表指定各列的值,列名与值需要一一对应. 如果insert语句所指定的列名列表包含了表中的所有列,那么可以将列名列表省略. create table student08 ( id number, name varchar2(20), sex varchar2(20), a

MyBatis动态批量插入、更新Mysql数据库的通用实现方案

一.业务背景 由于需要从A数据库提取大量数据同步到B系统,采用了tomikos+jta进行分布式事务管理,先将系统数据源切换到数据提供方,将需要同步的数据查询出来,然后再将系统数据源切换到数据接收方,进行批量的插入和更新操作, 关于数据源的切换可以参考之前的文章<spring+springMVC+Mybatis架构下采用AbstractRoutingDataSource.atomikos.JTA实现多数据源灵活切换以及分布式事务管理> 二.批量插入的具体实现 1.查询需要同步的数据: @Aut

java mysql大数据量批量插入与流式读取分析

总结下这周帮助客户解决报表生成操作的mysql 驱动的使用上的一些问题,与解决方案.由于生成报表逻辑要从数据库读取大量数据并在内存中加工处理后在 生成大量的汇总数据然后写入到数据库.基本流程是 读取->处理->写入. 1 读取操作开始遇到的问题是当sql查询数据量比较大时候基本读不出来.开始以为是server端处理太慢.但是在控制台是可以立即返回数据的.于是在应用 这边抓包,发现也是发送sql后立即有数据返回.但是执行ResultSet的next方法确实阻塞的.查文档翻代码原来mysql驱动默

SQL Server中中数据行批量插入脚本的存储实现

看到博友SQL Server MVP桦仔的一篇博文“将表里的数据批量生成INSERT语句的存储过程的实现”.我仔细看来博文中的两个存储代码,自我感觉两个都不太满意,都是生成的单行模式的插入,数据行稍微大些性能会受影响的.所在公司本来就存在第二个版本的类似实现,但是是基于多行模式的,还是需要手工添加UNAION ALL来满足多行模式的插入.看到这边博文和基于公司数据行批量脚本的存储的确定,这次改写和增强该存储的功能. 本存储运行于SQL Server 2005或以上版本,T-SQL代码如下: 1

原创:关于使用Mybatis插件自动生成造成批量插入转换成list集合的问题以及解决方案(转载请注明出处,谢谢!)

问题: 由于项目中需要批量插入的功能,然后我就用到了阿里的json包,将json数据转换成list集合在批量添加到数据库,但是这个过程中,我突然发现一个问题,之前接收前台传来的值是有的,但转换之后某些字段的值没有了,后面发现,原来是Mybatis自动生成插件做的怪,将实体类赋setter和getter方法时,并没有将属性大写,也就是说原本我的实体字段为gName;setter方法之后为setgName,这就违反了命名规则,但是阿里json包就出现了不能转换报Null的问题,经过试验,终于找到了解