jdbc 批量执行sql

最近有个需求是需要在java 后端执行导入,数据量比较大, 需要对数据进行很多操作,最后要执行插入数据操作, 一开始先组织好插入数据的sql语句放在数组中,使用的是 jdbcTemplate.batchUpdate()方法,后来发现当数据比较多 ,成千上万条时,他的插入效率比较慢,所以又改用了jdbc 的批量插入.插入速度有了很大的提速

方法1

直接使用了jdbctemplate内部封装的batchUpdate方法,他的底层也是用了 jdbc 的批量执行,但是执行效率要比 正常使用jdbc 批量执行要慢很多,插入2600条数据的20个字段左右的表用时40s 左右,

// sqls 为组织好的插入数据的sql数组,
//{"insert into user(id,name,pwd) values('1','a','123456')","insert into user(id,name,pwd) values('2','b','123456')",...   }
// j
public void insertData(String[] sqls,JdbcTemplate jdbctemplate){
	jdbctemplate.batchUpdate(sqls);
}

方法2

使用了 jdbc 的批量执行sql, 主要使用了addBatch(),executeBatch(),clearBatch()方法,
这样批量执行 大大的提高了执行效率,2600条数据 20个字段的表插入只用了4-5s,
下面方法控制每5000条sql执行一次,剩下不足500条最后再执行一次.

public void insertData2(String[] sqls,JdbcTemplate jdbctemplate){
	Connection conn = jdbcTemplate.getDataSource().getConnenction();
	conn.setAutoCommit(false);//设置连接对象的自动提交为false
	Statement statement = conn.createStatement();
	for(int i=0;i<sqls.length;i++){
		statement.addBatch(sqls[i]);
		if(i % 5000 ==0){
			statement.executeBatch(); // 批量执行
			conn.commit();  // 手动提交
			statement.clearBatch();  // 清楚之前批量执行的
		}
	}
	statement.executeBatch();
	conn.commit();
	statement.clearBatch();
}
注意:
  1. 数据库区别:

本项目用的是 oracle数据库, 而mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理的支持。 ?rewriteBatchedStatements=true 写在配置文件的url后面
本问题参考自
作者:Nemo
链接:https://www.cnblogs.com/blknemo/
来源:博客园

  1. 可能出现的sql错误(本项目未遇到)
  • Oracle数据库中打开的游标最大数为一定值,默认情况下是300,当代码到第二步时,循环中一个PreparedStatement占用了一个数据库游标,执行的循环超过这个数时就会产生游标数目溢出错误。
    解决办法:每次执行完PreparedStatement,都将PreparedStatement.close()下,释放掉这个资源就好了
    Exception in thread “main” java.sql.SQLException: ORA-00604: 递归 SQL 级别 1 出现错误
    ORA-01000: 超出打开游标的最大数
    ORA-00604: 递归 SQL 级别 1 出现错误
    ORA-01000: 超出打开游标的最大数
    ORA-01000: 超出打开游标的最大数

  • java.sql.SQLException:ORA-00054;资源正忙,但指定以NOWAIT方式获取资源,或者超时失败
    原因:数据库中存在未提交的记录

  • java.sql.SQLException 索引中丢失in或out参数
    原因:SQL语句有问题
    解决:jdbc进行字段拼接插入操作时,为string类型的加上单引号
    另外,用prepareStatement.setString(1, 字段值),可以防止字段值有单引号而破坏sql问题

  • java.sql.BathUpdateException:ORA-01461;仅能绑定要插入LONG列的LONG值
    原因:由于要插入的字段长度超出了数据库中表定义的字段长度
    --------------------------补充-----------------------------------
    varchar2是Oracle提供的特定数据类型
    varchar2(10)一般情况最多存5个汉字,10个字符。具体要看数据库使用的字符集:GBK(汉字2字节;英文1个;Oracle安装默认GBK编码格式);UTF-8(汉字3字节,英文1个)
    一般页面做输入字符串长度校验时,以数据库设计字段最大长度/3作为最大长度
    nvarchar(10)可以存10个汉字,10个字符
    当长度大于4000的时候就应该用CLOB,因为oracle的varchar2最多4000个字符

  • ORA-24816:在实际的LONG或LOB列之后提供了扩展的非LONG绑定数据
    原因:这个问题很奇怪,就算没有LONG类型的数据,全部都是VARCHAR2和CLOB在操作数据库更新的时候一直报这个错误
    解决:歪打正着,调整了一下各种更新字段位置,将放在前面的CLOB类型放在后面,就不报错了

可能发生的sql报错信息 转自CSDN博主「thankjj20160909」的原创文章
原文链接:https://blog.csdn.net/qq_36092584/article/details/80721904

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值