tch() JDBC使用MySQL处理大数据的时候,自然而然的想到要使用批处理,
普通的执行过程是:每处理一条数据,就访问一次数据库;
而批处理是:累积到一定数量,再一次性提交到数据库,减少了与数据库的交互次数,所以效率会大大提高
至于事务:事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功,默认是关闭事务的。
1. PreparedStatement使用批处理 executeBatch()
1.1. 不使用executeBatch(),而使用executeUpdate(),速度很慢
?
public static void main(String[] args) throws SQLException,ClassNotFoundException{
// TODO Auto-generated method stub
String url = "jdbc:mysql://localhost:3306/skyfin";
String username = "root";
String password = "skyfin";
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection(url,username,password);
String sql = "insert into user1(id,name) value(?,?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for(int i = 0;i<10000;i++){
preparedStatement.setInt(1, i);
preparedStatement.setString(2, "skyfin"+i);
preparedStatement.executeUpdate();
}
}
?
1.2. 而使用executeBatch()
public static void main(String[] args) throws SQLException,ClassNotFoundException{
// TODO Auto-generated method stub
String url = "jdbc:mysql://localhost:3306/skyfin";
String username = "root";
String password = "skyfin";
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection(url,username,password);
String sql = "insert into user1(id,name) value(?,?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for(int i = 0;i<10000;i++){
preparedStatement.setInt(1, i);
preparedStatement.setString(2, "skyfin"+i);
//preparedStatement.executeUpdate();
/*
* 使用executeBatch()
*/
preparedStatement.addBatch();
}
//执行批处理
preparedStatement.executeBatch();
}
?
注意:1. 如果使用了 addBatch() -> executeBatch() 还是很慢,那就得使用到这个参数了rewriteBatchedStatements=true (启动批处理操作)
在数据库连接URL后面加上这个参数: String dbUrl = "jdbc:mysql://localhost:3306/User? rewriteBatchedStatements=true";
2. 在代码中,pstmt的位置不能乱放,必须放在循环体外
2. 启用事务处理
?
public static void main(String[] args) throws SQLException,ClassNotFoundException{
// TODO Auto-generated method stub
String url = "jdbc:mysql://localhost:3306/skyfin";
String username = "root";
String password = "skyfin";
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection(url,username,password);
//关闭自动提交
connection.setAutoCommit(false);
String sql = "update user1 set name = ?where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for(int i = 0;i<10000;i++){
preparedStatement.setString(1, "loco"+i);
preparedStatement.setInt(2, i);
//preparedStatement.executeUpdate();
/*
* 使用executeBatch()
*/
preparedStatement.addBatch();
}
//执行批处理
preparedStatement.executeBatch();
preparedStatement.close();
//执行完后手动提交事务
connection.commit();
//打开自动提交
connection.setAutoCommit(true);
connection.close();
}
?
3. 事务和批处理混合使用
public static void main(String[] args) throws SQLException,ClassNotFoundException{
// TODO Auto-generated method stub
String url = "jdbc:mysql://localhost:3306/skyfin";
String username = "root";
String password = "skyfin";
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection(url,username,password);
//关闭自动提交
connection.setAutoCommit(false);
String sql = "update user1 set name = ?where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for(int i = 0;i<10000;i++){
preparedStatement.setString(1, "skyfin"+i);
preparedStatement.setInt(2, i);
//preparedStatement.executeUpdate();
/*
* 使用executeBatch()
*/
if (i>0&&i%500 == 0) {
preparedStatement.executeBatch();
//如果不想出错后,完全没保留数据,则可以没执行一次提交一次,但得保证数据不会重复
connection.commit();
}
preparedStatement.addBatch();
}
//执行批处理
preparedStateme