JDBC批处理插入更新示例
时间:2020-01-09 10:35:22 来源:igfitidea点击:
在本教程中,我们将看到如何使用JDBC批处理进行批处理插入或者更新。如果我们必须运行大量的SQL语句,则将它们作为批处理而不是作为单个命令访问每个命令的DB效率更高。
JDBC中批处理的方法
在JDBC Statement界面中,有以下方法可用于批量支持
- addBatch(String sql)–将给定的SQL命令添加到此Statement对象要批量执行的SQL命令列表中。
- clearBatch()–清空此Statement对象的当前SQL命令列表。
- executeBatch()–将一批命令提交给数据库以执行,如果所有命令成功执行,则返回更新计数数组。
在PreparedStatement中,还有另一种方法
- addBatch()–将参数化的SQL添加到要批量执行的命令列表中。
JDBC批量插入示例
在此批量插入示例中,我们将使用PreparedSatement将记录插入Employee表中,DB是MySQL。
在MySQL中,我们必须在连接字符串中添加rewriteBatchedStatements = true,以便在调用executeBatch()时将为INSERT准备的语句重写为多值插入。
因此,添加到批处理中的查询就像单个查询一样
插入TABLE_NAME(COL1,COL2)值(" val1"," val2")
插入TABLE_NAME(COL1,COL2)值(" val3"," val4")
插入TABLE_NAME(COL1,COL2)值(" val5"," val6")
被转换为多值插入
插入TABLE_NAME(COL1,COL2)值(" val1"," val2"),(" val3"," val4"),(" val5"," val6")
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBCBatchDemo {
public static void main(String[] args) {
Connection connection = null;
try {
// Load driver
Class.forName("com.mysql.cj.jdbc.Driver");
// connection object
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/theitroad?rewriteBatchedStatements=true",
"root", "admin");
String insertSQL = "INSERT INTO EMPLOYEE (FIRST_NAME, LAST_NAME, DEPARTMENT) values (?, ?, ?)";
int batchSize = 5;
// create Statement object
PreparedStatement preparedStatement = connection.prepareStatement(insertSQL);
for(int i = 1; i <= 10; i++){
preparedStatement.setString(1, "TestName"+i);
preparedStatement.setString(2, "LName"+i);
preparedStatement.setString(3, "Dept");
// Keep adding to batch
preparedStatement.addBatch();
// Execute batch in chunks
if(i%batchSize == 0){
preparedStatement.executeBatch();
}
}
// For the left over records
preparedStatement.executeBatch();
} catch (ClassNotFoundException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
在程序中,要注意的一些重要点是:
- URL中是否使用rewriteBatchedStatements = true-jdbc:mysql:// localhost:3306 / theitroad?rewriteBatchedStatements = true
- 在该程序中,总共5条记录中插入了10条记录。一个好主意是将较小的批处理大批量地分割并执行。例如,假设我们正在运行一批1000个插入,而不是一次将所有1000条记录发送到DB,则最好执行100条记录的批次。
- 如果批处理更新中的命令之一无法正确执行,则executeBatch()方法将引发BatchUpdateException,并且JDBC驱动程序可能会或者可能不会继续处理批处理中的其余命令。
- 在MySQL DB中,如果抛出BatchUpdateException,则不处理该批处理中的其余命令,但是将保留在异常之前所做的更改(如果已执行executeBatch()命令)。例如,如果我们正在为5条记录的块执行批处理,并且第7条insert语句引发异常,则已处理的记录1-5将保留。如果要回滚所有更改,则应在事务中批量运行。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBCBatchDemo {
public static void main(String[] args) {
Connection connection = null;
try {
// Load driver
Class.forName("com.mysql.cj.jdbc.Driver");
// connection object
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/theitroad?rewriteBatchedStatements=true",
"root", "admin");
connection.setAutoCommit(false);
String insertSQL = "INSERT INTO EMPLOYEE (FIRST_NAME, LAST_NAME, DEPARTMENT) values (?, ?, ?)";
int batchSize = 5;
// create Statement object
PreparedStatement preparedStatement = connection.prepareStatement(insertSQL);
for(int i = 1; i <= 10; i++){
preparedStatement.setString(1, "TestName"+i);
preparedStatement.setString(2, "LName"+i);
preparedStatement.setString(3, "Dept");
// Keep adding to batch
preparedStatement.addBatch();
// Execute batch in chunks
if(i%batchSize == 0){
preparedStatement.executeBatch();
}
}
// For the left over records
preparedStatement.executeBatch();
connection.commit();
} catch (ClassNotFoundException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

