一、事务
1、JDBC程序中当一个Connection对象创建时,默认情况下是自动提交事务:每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚。
2、JDBC程序中为了让多个SQL语句作为一个整体执行,需要使用事务
3、调用Connection的setAutoCommit(false)可以取消自动提交事务
4、在所有的SQL语句都成功执行后,调用Connection的 commit();方法提交事务
5、在其中某个操作失败或者出现异常时,调用Connection的 rollback();方法回滚事务
package com.javase.jdbc.transaction_;
import com.javase.jdbc.utils.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* 演示在JDBC中如何使用事务
*/
public class Transaction01 {
public static void main(String[] args) {
//noTransaction();
useTransaction();
}
//没有使用事务
public static void noTransaction() {
//操作转账的业务
//1. 得到连接
Connection connection = null;
//2. 组织sql语句
String sql = "update ACCOUNT set balance = balance - 100 where id = 1";
String sql1 = "update ACCOUNT set balance = balance + 100 where id = 2";
//3. 创建PreparedStatement对象
PreparedStatement preparedStatement = null;
try {
//在默认情况下,connection对象是默认自动提交
connection = JDBCUtils.getConnection();
preparedStatement = connection.prepareStatement(sql);
//执行第一条sql
preparedStatement.executeUpdate();
int i = 1 / 0;
//执行第二条sql
preparedStatement = connection.prepareStatement(sql1);
preparedStatement.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JDBCUtils.close(null, preparedStatement, connection);
}
}
//使用事务
public static void useTransaction(){
//操作转账的业务
//1. 得到连接
Connection connection = null;
//2. 组织sql语句
String sql = "update ACCOUNT set balance = balance - 100 where id = 1";
String sql1 = "update ACCOUNT set balance = balance + 100 where id = 2";
//3. 创建PreparedStatement对象
PreparedStatement preparedStatement = null;
try {
//在默认情况下,connection对象是默认自动提交
connection = JDBCUtils.getConnection();
//将connection设置为不自动提交
connection.setAutoCommit(false);//开启了事务
preparedStatement = connection.prepareStatement(sql);
//执行第一条sql
preparedStatement.executeUpdate();
//int i = 1 / 0;//抛出异常
//执行第二条sql
preparedStatement = connection.prepareStatement(sql1);
preparedStatement.executeUpdate();
//提交事务
connection.commit();
} catch (SQLException throwables) {
//这里我们可以进行回滚,即撤销执行的sql
//默认回滚到事务开始的状态
System.out.println("执行发送了异常,撤销执行的sql");
try {
connection.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
throwables.printStackTrace();
} finally {
JDBCUtils.close(null, preparedStatement, connection);
}
}
}
二、批处理
1、当需要成批插入或者更新记录时,,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率。
2、JDBC的批量处理语句包括下面方法:
addBatch():添加需要批量处理的SQL语句或参数
executeBatch():执行批量处理语句
clearBatch():清空批处理包的语句
3、JDBC连接Mysql时,如需使用批处理功能,请在url中加参数 ?rewriteBatchedStatements=true
4、批处理往往和PreparedStatement一起搭配使用,可以既减少编译次数,又减少运行次数,效率大大提高
package com.javase.jdbc.batch_;
import com.javase.jdbc.utils.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* 演示java的批处理
*/
public class Batch01 {
public static void main(String[] args) throws Exception {
//noBatch();
batch();
}
//传统方法,添加5000条数据到admin2
public static void noBatch() throws Exception {
Connection connection = JDBCUtils.getConnection();
String sql = "insert into admin2 values(null, ?, ?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
System.out.println("开始执行");
long start = System.currentTimeMillis();//开始时间
for (int i = 0; i < 5000; i++) {
preparedStatement.setString(1, "jack" + i);
preparedStatement.setString(2, "666");
preparedStatement.executeUpdate();
}
long end = System.currentTimeMillis();//结束时间
System.out.println("传统的方式耗时:" + (end - start));
//关闭连接
JDBCUtils.close(null, preparedStatement, connection);
}
//使用批量方式添加数据
public static void batch() throws Exception {
Connection connection = JDBCUtils.getConnection();
String sql = "insert into admin2 values(null, ?, ?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
System.out.println("开始执行");
long start = System.currentTimeMillis();//开始时间
for (int i = 0; i < 5000; i++) {
preparedStatement.setString(1, "jack" + i);
preparedStatement.setString(2, "666");
//将sql语句添加到批处理包中
preparedStatement.addBatch();
//当有1000条记录时,再批量执行
if ((i + 1) % 1000 == 0) {
preparedStatement.executeBatch();
//清空
preparedStatement.clearBatch();
}
}
long end = System.currentTimeMillis();//结束时间
System.out.println("批量的方式耗时:" +