关于Java的PreparedStatement的executeBatch方法及海量数据存储时的主键重复问题

47 篇文章 0 订阅

PreparedStatement的executeBatch方法在执行insert语句时主键重复异常会被SQLiteException捕获,不会被BatchUpdateException捕获,被BatchUpdateException捕获可根据getUpdateCounts方法得到已更新的记录数。

executeBatch方法本身是int[],它的length是成功执行的记录数,但执行时遇到异常,就不会走到返回,所以无法知道在insert哪一条记录时异常,PreparedStatement的已知方法也无法做到。

executeBatch方法不能执行select。

ResultSet的getString(columnIndex)等方法,columnIndex从1开始,而不是0。set也是从1开始,set(myString,1)。

PreparedStatement最大的好处就是在于重复使用同一模板,这样服务器只对SQL模板进行一次语法校验和函数编译,其中参数编译后都会成为函数的参数,执行SQL语句时只是把参数代入到函数中完成调用。这样就能赋予其不同的参数来重复的使用它,这就是提高效率的原因。

海量数据循环提交,每次提交大量insert,如果想避免主键重复异常有以下方法:
1、每条记录select后决定insert还是update。
2、全部insert,异常时遍历此次提交的记录,select未成功的insert,从而将未成功的update。
3、全部insert,异常时逐条插入,不成功时update。
4、忽略主键,全部insert,然后delete多余的主键重复记录。
5、忽略主键,全部insert到临时表,然后遍历记录,每个主键select有效记录。
6、(推荐)将insert前的主键全部缓存进Vector或Array中,insert前对比缓存,如果有改为update,如果insert的记录可能主键重复,insert后将主键更新进缓存中。

缓存时,推荐Array,select count(主键) from 表;能得到Array大小,写入速度快于Vector,因为Vector动态分配内存。
百万级记录查询,有索引时,i5CPU,1332434条记录缓存进Vector,14172毫秒,而Array是1257毫秒。

Connection的prepareStatement方法的参数为Sql语句,且必须有;,如prepareStatement("insert into A(a, b, c, d, id) values (?,?,?,?,?);")。

表有索引,会加快select速度,减慢insert和update速度。

百万级记录查询,有索引时,i5CPU,1332434条记录全部各查一次耗时在1332435毫秒,即22.20725分钟左右。

图片文件可用字节流存储,如PreparedStatement的setBinaryStream(int parameterIndex, java.io.InputStream x,int length)方法,
字节流格式举例:89 50 4E 0D 0A

插入Blob类型的数据时,必须用PreparedStatement,因为Blob类型的数据是不能够用字符串来拼的。推荐用法:Connection的setAutoCommit(false);后,使用ResultSet的getBinaryStream 方法和PreparedStatement的setBinaryStream方法对BLOB进行读写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风铃峰顶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值