对于需要批量插入数据库操作JDBC有多重方式,本利从三个角度对Statement和PreparedStatement两种执行方式进行分析,总结较优的方案。

当前实现由如下条件:

  执行数据库:Mysql

执行数据数量:10万条

执行前提:执行差入数据库钱均需要提供空表,防止数据量大造成的影响

执行方式:Statement和PreparedStatement两种方式

执行步骤开始:

1、创建表

 CREATE TABLE T_PRODUCT (
ID bigint(12) NOT NULL AUTO_INCREMENT COMMENT '主键',
NAME varchar(60) NOT NULL COMMENT '产品名称',
WEIGHT varchar(60) NOT NULL COMMENT '产品重量',
MARK varchar(60) NOT NULL COMMENT '产品说明',
PRIMARY KEY (ID)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='产品表';

2、编写操作数据库工具类

 package com.luwei.test.jdbc;

 import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle; /**
* <Description> TODO<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2017年1月9日 <br>
* @since V1.0<br>
* @see com.luwei.test.jdbc <br>
*/
public class JdbcTemplate {
private static String DRIVER_CLASS_NAME = null;
private static String URL = null;
private static String USERNAME = null;
private static String PASSWORD = null; static {
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
DRIVER_CLASS_NAME = bundle.getString("jdbc.driverClassName");
URL = bundle.getString("jdbc.url");
USERNAME = bundle.getString("jdbc.username");
PASSWORD = bundle.getString("jdbc.password");
} /**
*
* <Description> 获取数据库连接<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2017年1月9日 下午10:19:41 <br>
* @return
* @throws Exception
* <br>
*/
public static Connection getConnection() throws Exception {
Class.forName(DRIVER_CLASS_NAME);
Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
return connection;
} /**
*
* <Description> 提交事务<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2017年1月9日 下午10:20:48 <br>
* @param connection
* <br>
*/
public static void commit(Connection connection) {
try {
connection.commit();
}
catch (SQLException e) {
e.printStackTrace();
}
} /**
*
* <Description> 开启事务<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2017年1月9日 下午10:23:56 <br>
* @param connection
* <br>
*/
public static void beginTx(Connection connection) {
try {
connection.setAutoCommit(false);
}
catch (SQLException e) {
e.printStackTrace();
}
} /**
*
* <Description> 回滚<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2017年1月9日 下午10:24:33 <br>
* @param connection
* <br>
*/
public static void rollback(Connection connection) {
try {
connection.rollback();
}
catch (SQLException e) {
e.printStackTrace();
}
} /**
*
* <Description> TODO<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2017年1月9日 下午10:28:49 <br>
* @param statement
* @param connection
* <br>
*/
public static void releaseDb(Statement statement, Connection connection) {
try {
statement.close();
connection.close();
}
catch (SQLException e) {
e.printStackTrace();
}
}
}

3、执行数据库插入操作

3.1、使用Statement直接插入,三次执行耗时:41979 42608 42490

 @Test
public void testStatement() {
Connection connection = null;
Statement statement = null;
try {
connection = JdbcTemplate.getConnection();
JdbcTemplate.beginTx(connection); statement = connection.createStatement();
long begin = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
String sql = "insert into t_product values(null,'name_" + i + "','120kg','mark_" + i + "')";
statement.execute(sql);
}
long end = System.currentTimeMillis();
System.out.println(end - begin);
JdbcTemplate.commit(connection);
}
catch (Exception e) {
e.printStackTrace();
JdbcTemplate.rollback(connection);
}
finally {
JdbcTemplate.releaseDb(statement, connection);
}
}

3.2、使用PreparedStatement直接插入,三次执行耗时:22808 24675 22281

 @Test
public void testPreparedStatement() {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = JdbcTemplate.getConnection();
JdbcTemplate.beginTx(connection);
String sql = "insert into t_product values(null,?,?,?)"; statement = connection.prepareStatement(sql);
long begin = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
statement.setString(1, "name_" + i);
statement.setString(2, "120kg");
statement.setString(3, "mark_" + i);
statement.executeUpdate();
}
long end = System.currentTimeMillis();
System.out.println(end - begin);
JdbcTemplate.commit(connection);
}
catch (Exception e) {
e.printStackTrace();
JdbcTemplate.rollback(connection);
}
finally {
JdbcTemplate.releaseDb(statement, connection);
}
}

3.3、使用BatchStatement直接插入,三次执行耗时:15342 15235 15485

 @Test
public void testBatchStatement() {
Connection connection = null;
Statement statement = null;
try {
connection = JdbcTemplate.getConnection();
JdbcTemplate.beginTx(connection); statement = connection.createStatement();
long begin = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
String sql = "insert into t_product values(null,'name_" + i + "','120kg','mark_" + i + "')";
statement.addBatch(sql); if ((i + 1) % 100 == 0) {
statement.executeBatch();
statement.clearBatch();
}
}
statement.executeBatch();
statement.clearBatch();
long end = System.currentTimeMillis();
System.out.println(end - begin);
JdbcTemplate.commit(connection);
}
catch (Exception e) {
e.printStackTrace();
JdbcTemplate.rollback(connection);
}
finally {
JdbcTemplate.releaseDb(statement, connection);
}
}

3.4、使用BatchPreparedStatement直接插入,三次执行耗时:21913 22045 23291

 @Test
public void testBatchPreparedStatement() {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = JdbcTemplate.getConnection();
JdbcTemplate.beginTx(connection);
String sql = "insert into t_product values(null,?,?,?)"; statement = connection.prepareStatement(sql);
long begin = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
statement.setString(1, "name_" + i);
statement.setString(2, "120kg");
statement.setString(3, "mark_" + i);
statement.addBatch();
if ((i + 1) % 100 == 0) {
statement.executeBatch();
statement.clearBatch();
}
}
statement.executeBatch();
statement.clearBatch();
long end = System.currentTimeMillis();
System.out.println(end - begin);
JdbcTemplate.commit(connection);
}
catch (Exception e) {
e.printStackTrace();
JdbcTemplate.rollback(connection);
}
finally {
JdbcTemplate.releaseDb(statement, connection);
}
}

3.5、使用采用多Value值Statement直接插入,三次执行耗时:2931 3007 3203 2964

 @Test
public void testMutilValueStatement() {
Connection connection = null;
Statement statement = null;
try {
connection = JdbcTemplate.getConnection();
JdbcTemplate.beginTx(connection); statement = connection.createStatement(); StringBuffer sql = new StringBuffer("insert into t_product values");
long begin = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
if (i != 0) {
sql.append(",");
}
sql.append("(null,'name_" + i + "','120kg','mark_" + i + "')");
}
statement.execute(sql.toString());
long end = System.currentTimeMillis();
System.out.println(end - begin);
JdbcTemplate.commit(connection);
}
catch (Exception e) {
e.printStackTrace();
JdbcTemplate.rollback(connection);
}
finally {
JdbcTemplate.releaseDb(statement, connection);
}
}

3.6、使用采用多Value值PreparedStatement直接插入,三次执行耗时:3356 3218 3233

 @Test
public void testMutilValuePreparedStatement() {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = JdbcTemplate.getConnection();
JdbcTemplate.beginTx(connection); StringBuffer sql = new StringBuffer("insert into t_product values");
long begin = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
if (i != 0) {
sql.append(",");
}
sql.append("(null,'name_" + i + "','120kg','mark_" + i + "')");
}
statement = connection.prepareStatement(sql.toString());
statement.executeUpdate();
long end = System.currentTimeMillis();
System.out.println(end - begin);
JdbcTemplate.commit(connection);
}
catch (Exception e) {
e.printStackTrace();
JdbcTemplate.rollback(connection);
}
finally {
JdbcTemplate.releaseDb(statement, connection);
}
}

通过以上时间结果得出如下数据表格:

总结:通过如上的数据对比发现

  1、PreparedStatement执行数据库插入比使用Statement执行数据库插入明显有性能优势,原因归功于PreparedStatement能够预先对SQL进行编译,做到执行时进行SQL共享

  2、执行数据库批量操作是使用Batch方式对数据库采用批次操作能够明显提升数据库操作性能能

  3、不管是直接多次插入数据库还是采用Batch方式执行数据库的插入,均会发送多次SQL脚本去执行,这样明显没有发送一次SQL脚本执行来的效率高

  4、采用单SQL执行数据库批量操作时Statement对比PreparedStatement有微弱的优势,可能是Statement不需要判断注参的原因吧

JDBC批量插入数据效率分析的更多相关文章

  1. JDBC批量插入数据优化,使用addBatch和executeBatch

    JDBC批量插入数据优化,使用addBatch和executeBatch SQL的批量插入的问题,如果来个for循环,执行上万次,肯定会很慢,那么,如何去优化呢? 解决方案:用 preparedSta ...

  2. MySQL:JDBC批量插入数据的效率

    平时使用mysql插入.查询数据都没有注意过效率,今天在for循环中使用JDBC插入1000条数据居然等待了一会儿 就来探索一下JDBC的批量插入语句对效率的提高 首先进行建表 create tabl ...

  3. android批量插入数据效率对比

    对比在android中批量插入数据的3中方式对比(各插入1W条数据所花费的时间): 1. 一个一个插入 /** * 向表中插入数据 * * @param openHelper * @param app ...

  4. 【实践】jdbc批量插入数据

    参考文献:http://my.oschina.net/u/1452675/blog/203670 http://superjavason.iteye.com/blog/255423 /*测试批量写入数 ...

  5. jdbc批量插入数据

    //插入很多书(批量插入用法) public void insertBooks(List<Book> book) {   final List<Book> tempBook=b ...

  6. Java使用JDBC连接数据库逐条插入数据、批量插入数据、以及通过SQL语句批量导入数据的效率对比

    测试用的示例java代码: package com.zifeiy.test.normal; import java.io.File; import java.io.FileOutputStream; ...

  7. 向mysql中批量插入数据的性能分析

    MYSQL批量插入数据库实现语句性能分析 假定我们的表结构如下 代码如下   CREATE TABLE example (example_id INT NOT NULL,name VARCHAR( 5 ...

  8. JDBC(五)—— 批量插入数据

    批量插入数据 @Test public void testInsert() throws Exception { Connection conn = null; PreparedStatement p ...

  9. Mybatis与JDBC批量插入MySQL数据库性能测试及解决方案

    转自http://www.cnblogs.com/fnz0/p/5713102.html 不知道自己什么时候才有这种钻研精神- -. 1      背景 系统中需要批量生成单据数据到数据库表,所以采用 ...

随机推荐

  1. LSI MegaCl i命令使用1

    MegaCli命令使用:cd /opt/MegaRAID/MegaCli/MegaCli -AdpAllInfo -aAll     [显示所有适配器信息]MegaCli -LDInfo -Lall ...

  2. HDU -2674 N!Again(小技巧)

    这道题有个小技巧,就是既然是n!,那么对2009求余,只要大于2009!,那么一定是0,在仔细想想会发现,根本到不了2009,只要到2009的最大质因数就行了,为什么呢?因为最大质因数是最大的一个不能 ...

  3. Matcher Pattern 正则表达式 示例

    示例 public class Test {     public static void main(String[] args) throws IOException {         Patte ...

  4. 设计模式之—简单工厂模式<Simple Factory Pattern >

    简单工厂模式结构图: 简单工厂模式以简单的加减乘除运算为例: 运算符类(Operation): namespace CalcTest.Simple_Factory_patterns { class O ...

  5. python运行时间计算之timeit

    timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000) stmt:statement ...

  6. Javascript 常用函数【1】

    1:基础知识 1 创建脚本块 1: <script language=”JavaScript”> 2: JavaScript code goes here 3: </script&g ...

  7. access 2007 vba 开发中学到的知识(二)

    文件的导入和导出 excel 'excel导入Private Sub btnInExcel_Click() Dim strSelectFile As StringWith Application.Fi ...

  8. validate插件深入篇

    1.使用valid()来验证表单是否填写正确: <form id="mainform"> <button id="check">< ...

  9. 使用scrapy制作的小说爬虫

    使用scrapy制作的小说爬虫 爬虫配套的django网站  https://www.zybuluo.com/xuemy268/note/63660 首先是安装scrapy,在Windows下的安装比 ...

  10. 遍历元素绑定事件时作用域是怎么回事啊,为什么要用this关键字,而直接使用元素本身就不行?

    如下代码,将this改为rows[i]为啥不起作用了 var rows = document.getElementsByTagName("tr"); for(var i=0;i&l ...