0
点赞
收藏
分享

微信扫一扫

关于JDBC MySql PreparedStatement executeBatch过慢的问题解决------亲身经历

凌得涂 2023-03-15 阅读 98


话不多说,先看源码-----

package com.test.curd;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestBatch {
private static String driver ="com.mysql.cj.jdbc.Driver";
private static String url="jdbc:mysql://127.0.0.1:3306/gavin?useUnicode=true&rewriteBatchedStatements=true&useServerPrepStmts=true";;
private static String user="gavin";
private static String password="955945";
static long start =0;
static long end =0;
public static void main(String[] args) {
testAddBatch();
}
// 定义一个方法,向部门表增加1000条数据
public static void testAddBatch(){
Connection connection = null;
PreparedStatement preparedStatement=null;
try{
Class.forName(driver);
connection = DriverManager.getConnection(url, user,password);
String sql="insert into accounting1 values (DEFAULT,?,?,?,now());";
preparedStatement = connection.prepareStatement(sql);//这里已经传入SQL语句
//设置参数
start = System.currentTimeMillis();
for (int i = 1; i <= 10666; i++) {
preparedStatement.setString(1, "Mary");
preparedStatement.setString(2, "123456");
preparedStatement.setDouble(3, 200.00d);
preparedStatement.addBatch();// 将修改放入一个批次中
if(i%1000==0){
preparedStatement.executeBatch();//1000条一提交
preparedStatement.clearBatch();// 清除批处理中的数据
}
}
/*
* 整数数组中的元素代表执行的结果代号
* SUCCESS_NO_INFO -2
* EXECUTE_FAILED -3
* */
/*int[] ints = */
preparedStatement.executeBatch();
preparedStatement.clearBatch();
}catch (Exception e){
e.printStackTrace();
}finally {
end=System.currentTimeMillis();

System.out.println(end-start);
}
}
}

执行时间------

关于JDBC MySql PreparedStatement executeBatch过慢的问题解决------亲身经历_mysql

可以看到虽然开启了预编译和缓存,但是执行时间仍然很慢,原因就在于自动提交,看一下API中的说法-----

Newlycreated Connection objects are in auto-commit mode by default, which means thatindividual SQL statements are committed automatically when the statement iscompleted. To be able to group SQL statements intotransactions and commit them or roll them back as a unit, auto-commit must bedisabled by calling the method setAutoCommit with false as its argument. Whenauto-commit is disabled, the user must call either the commit or rollbackmethod explicitly to end a transaction

翻译过来就是如果自动提交为true,则所有的sql都当作单个事务进行处理提交,如果设置为 false则视为事务一块提交(commit()或者回滚rollback(),所以第一种方式虽然设置了 缓存,预编译,但是还有自动提交没有设置;

package com.test.curd;

import java.sql.*;

public class AdTest {

//准备数据库连接的条件

final static String URL = "jdbc:mysql://127.0.0.1:3306/gavin?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&cachePrepStmts=true&reWriteBatchedStatements=true&useServerPrepStmts=true";
final static String USER = "gavin";
final static String PASSWORD = "955945";
static long start =0;
static long end =0;
public static void main(String[] args) {
addTest();
}


public static void addTest() {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
//Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection(URL, USER, PASSWORD);
String sql = "insert into accounting values (DEFAULT,?,?,?,now());";
start=System.currentTimeMillis();

preparedStatement = connection.prepareStatement(sql);
connection.setAutoCommit(false);
for (int i = 1; i <=10666; i++) {

preparedStatement.setString(1, "Mary");
preparedStatement.setString(2, "123456");
preparedStatement.setDouble(3, 200.00d);

//将上述语句加入到批处理
preparedStatement.addBatch();
if (i % 1000 == 0) {
connection.commit();
preparedStatement.executeBatch();

preparedStatement.clearBatch();
}

}
preparedStatement.executeBatch();
preparedStatement.clearBatch();
end=System.currentTimeMillis();
System.out.println(end-start);
} catch (Exception e) {
e.printStackTrace();
try {
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
} finally {
if (null != preparedStatement) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (null != connection) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}

}

}
}

关于JDBC MySql PreparedStatement executeBatch过慢的问题解决------亲身经历_数据库_02

注意一点---------

一定要记住处理完之后要提交或者遇到异常要回滚!

如果不提交那么仅设置自动提交为true也是达不到效果的;


举报

相关推荐

0 条评论