对于需要批量插入数据库操作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. css之z-index深度解析

    (几个重点概念解析) 一.层叠上下文 层叠上下文:如果一个元素拥有层叠上下文.那么就代表这个元素在页面的z轴上是有定位的. 什么元素拥有 层叠上下文:a.根元素.b.z-index值为数值的元素.c. ...

  2. RadioGroup单选按钮排版

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools= ...

  3. mssql SUBSTRING和charindex的用法

    在工作中用到的例子: select * FROM [CSGDC.DataETLDB].[dbo].[StrategiesList] where strategy_name like '%基建系统%' ...

  4. ORACLE SQL单行函数(三)【weber出品必属精品】

    16.L:代表本地货币符,这个和区域有关.这个时候我们想来显示一下人民币的符号:¥ $ vi .bash_profile ---写入如下内容: export NLS_LANG='SIMPLIFIED ...

  5. MFC 堆栈溢出 test dword ptr [eax],eax ; probe page.

    今天调试程序的时候,发现一个奇怪的问题,之前调试都没问题的,今早加了一点东西,就出现错误,跳到调试位置,如下4行红色部分 ; Find next lower page and probe cs20: ...

  6. uva10020 贪心

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  7. 转载:Java连接MySQL 数据库的正确操作流程

    转载网址:http://www.bitscn.com/pdb/mysql/201005/186551.html       以下的文章主要介绍的是Java连接MySQL 数据库(以MySQL数据库为例 ...

  8. thinkphp基础入门(2)

    第一节介绍了thinkphp基本路径问题,第二节将介绍thinkphp的常见用法(M层跟V层) 我们先在Controller层新建个IndexController.class.php(新建文件的格式为 ...

  9. 文成小盆友python-num12 Redis发布与订阅补充,python操作rabbitMQ

    本篇主要内容: redis发布与订阅补充 python操作rabbitMQ 一,redis 发布与订阅补充 如下一个简单的监控模型,通过这个模式所有的收听者都能收听到一份数据. 用代码来实现一个red ...

  10. recovery编译汉化

    当BoardConfig.mk中定义了recovery的字体且为中文字体时,自动编译为中文版,否则编译为英文版 例如: BOARD_USE_CUSTOM_RECOVERY_FONT := \" ...