对于需要批量插入数据库操作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. git 取消追踪

    git rm --cached filePath这个操作不会删除这个文件

  2. css的clip裁剪

    clip 属性是用来设置元素的形状.用来剪裁绝对定位元素(absolute or fixed). clip有三种取值:auto |inherit|rect.inherit是继承,ie不支持这个属性, ...

  3. javascript 中寻找性能瓶颈

    1.如果一个段代码很耗时的话你可以注释掉一部分你认为是很耗时的,或者干脆全部注释掉,然后再一点一点的解开. 2.js优化中最主要的还是对dom操作的优化,单纯的js执行时间是很短的,而js和dom之间 ...

  4. js接收复选框的值

    <td><input type="checkbox" class="title" name="title" value=& ...

  5. tomcat startup.sh提示java.lang.OutOfMemoryError: PermGen space

    JAVA_OPTS="-server -XX:PermSize=512M -XX:MaxPermSize=1024m"if [ -z "$LOGGING_MANAGER& ...

  6. Javascript预解析、作用域、作用域链

    最近在看js的一些资料,总结一下昨晚看到的js作用域方面的知识,不准确的地方希望留言指正! 先看片段js代码如下: < script type="text/javascript&quo ...

  7. 武汉科技大学ACM :1007: A+B for Input-Output Practice (VII)

    Problem Description Your task is to Calculate a + b. Input The input will consist of a series of pai ...

  8. 编辑一个类库项目 即*.csproj这个文件的正确方式

    以前总是用记事本打开,删除一些或增加一些已修改的文件 今天才知道,正确的方式为: 右键单击类库,选择“卸载项目”,然后再右键单击已卸载变为灰色的类库,选择“编辑*.csproj” 编辑完了重新加载一下 ...

  9. UML中聚合和组合的区别

    聚合 聚合其实是关联的一个特例,表示了两个对象之间“part of(部分-整体)”的关系,是一种弱关联,部分的生命周期可以超越整体.在UML中,用整体端有空心菱形箭头的双向关联修饰聚合.聚合的示例如下 ...

  10. 转:初学者,手工注入测试方法小节 (出处:: 51Testing软件测试网--jie)

    1.加入单引号 ’提交,  结果:如果出现错误提示,则该网站可能就存在注入漏洞.    2.数字型判断是否有注入; 语句:and 1=1 ;and 1=2 (经典).' and '1'=1(字符型)  ...