admin 管理员组

文章数量: 1086019


2024年6月11日发(作者:groupby子句)

龙源期刊网

基于Mybatis框架的批量数据插入的性能问

题的探讨

作者:魏静敏 刘欢杰

来源:《计算机光盘软件与应用》2013年第19期

摘 要:本文首先提出了一个基于Mybatis框架下针对ORACLE的批量数据插入的性能问

题,然后针对该问题进行了调查,给出了问题的解决方法,并针对提出的方法进行了性能测试

和比较。本文给开发者解决基于java的批量数据插入的性能问题提供了一个思路。

关键词:ORACLE;Mybatis;批量数据插入;性能优化

中图分类号:TP393.09

1 问题描述

在进行web项目的开发中,数据库使用的是ORACLE11G,O/R层使用的是Mybaits3.1。

在进行页面的某个操作时,需要向DB中插入批量的数据,数据大约不足1000条左右,开发

者按照普通的写法,通过for循环,每次调用DB的insert操作进行一条数据的插入,从log文

件分析,全部数据的插入大约需要4,5秒钟,加上其他的处理,画面刷新大约需要6秒钟,

无法满足客户的要求。

2 调查过程

针对该页面反映慢的问题,分析得出批量数据插入的性能提升是问题的关键,因为它大约

占用了整个处理的85%的时间,如果能将它的性能进行优化,很大程度上能够解决该问题。首

先分析代码发现,该DB插入处理是通过for循环每次插入一条数据进行的。尽管大家知道

Mybatis本身采用的是连接池技术,每次DB操作不需要进行DB的打开和关闭,这样节省了

时间,但是进行上千次的sql文操作也需要花费大量的时间,因此考虑能不能执行一次插入操

作将所有数据登录到DB中,即实现批量插入。通过调查,方案有以下2个。

方案一:针对mybatis框架的。对于不同的DB类型,有以下两种写法。

(1)DB类型为Mysql的情况,可以利用SQL:insert into table values ('a1','a2')

('b1','b2')('c1','c2')...,Mybatis的map文件中的写法如下。

insert into table (id,name) values

龙源期刊网

(#{},{})

(2)如果DB使用的是ORACLE, 1)的写法不适用,可以利用SQL:

insert into table select 'a1','a2' from dual union all select 'b1','b2' from dual union all select

'c1','c2' from dual ,

Mybatis的map文件中的写法如下:

insert into table (id,name)

select #{,jdbcType=VARCHAR},

#{,jdbcType=VARCHAR}} from dual

但是,在一条命令SQL引擎默认是一次最多插入1000条记录,最多2100个字段参数,

一次处理海量数据容易引起以下两个错误:

The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is

incorrect. Too many parameters were provided in this RPC request. The maximum is 2100.和The

number of row value expressions in the INSERT statement exceeds the maximum allowed number of

1000 row values.

所以插入的时候还要处理一下,如果超过这2个指标的话,就需要做多次插入。以上(方

案一)的基本原理就是将所有被插入的数据生成一个select子句,这样通过执行一次insert语

句将该select的数据集插入到DB中。

方案二:不基于任何框架,利用PreparedStatement对象。

具体写法如下

try {

龙源期刊网

String url = "jdbc:oracle:thin:@IP:1521:orcl"; // orcl为数据库的SID

String user = "oracle";

String password = "oracle";

StringBuffer sql = new StringBuffer();

("insert into table(id,name) values (?,?)");

e("Driver");

Connection con = (Connection) nection(url,user,password);

// 关闭事务自动提交

oCommit(false);

Long startTime = tTimeMillis();

PreparedStatement pst = (PreparedStatement) eStatement(ng());

for (int i = 0; i < (); i++) {

Item item = (Item)(i);

ing(1, item .getId());

ing(2, item .getName());

// 把一个SQL命令加入命令列表

ch();

}

// 执行批量更新

eBatch();

// 语句执行完毕,提交本事务

龙源期刊网

();

} catch (ClassNotFoundException e) {

tackTrace();

} catch (SQLException e) {

tackTrace();

}finally{

If(pst!=null){

Try{();}catch(SQLException e){}

}

If(con!=null){

Try{conclose();}catch(SQLException e){}

}

}

3 性能测定

针对原来的方法和以上2种方法,进行了性能试验,结果如下表1所示。

4 结束语

本文通过具体实例,描述了基于java对ORACL进行批量数据插入操作的性能优化的方

法。并针对提出的优化方法进行了实际的性能测试,给出了各种方法的测试结果。为开发者进

行java的批量数据插入提供了一个好的方法。

参考文献:

[1]邱小彬,周南,虞萍.基于JAVA的批量数据导入导出探讨[J].农业网络信息,2008-10-

26.

龙源期刊网

[2]徐雯,高建华.基于Spring MVC及MyBatis的Web应用框架研究[J].微型电脑应用,

2012-07-20.

[3]尹帮治.基于VC#的Excel表格与SQL Server数据库的批量数据导入导出技术研究[J].企

业技术开发,2008-08-01.

作者单位:沈阳工学院,辽宁抚顺 113122;东软集团股份有限公司,沈阳 110179


本文标签: 数据 插入 批量 进行 性能