JDBC高级
1.批处理
有时候我们需要执行大批量的增删改时,可以使用 jdbc 的批处理,它能有效的提高执行效率。实现批处理可以使用 Statement 与 PreparedStatement 完成,通常在使用中常用的 API 有三个 addBatch(sql)、executeBatch() 和 clearBatch(),分别完成 SQL 的追加、执行与清除。清除主要是为了当批处理数据量过大时导致内存泄露。
案例:
private static void t1() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false", "root", "123456");
PreparedStatement statement = connection.prepareStatement("insert into user (name,password,age) values (?,?,18)");
for (int i = 0; i < 50000; i++) {
System.out.println(i);
statement.setString(1, "name" + i);
statement.setString(2, "123" + i);
statement.addBatch();
if (i % 1000 == 0) {
//防止内存溢出
statement.executeBatch();
statement.clearBatch();
}
}
statement.executeBatch();
statement.close();
connection.close();
}
练习:
1.使用 jdbc 的批量操作完成 user(name:admin,password:000000)…user(name:admin,password:999999)的数据插入。
参考代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JdbcTest {
public static void main(String[] arg) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false", "root", "123456");
PreparedStatement statement = connection.prepareStatement("insert into user (name,password,age) values (?,?,18)");
for (int i = 0; i < 1000000; i++) {
System.out.println(i);
statement.setString(1, "admin");
statement.setString(2, String.format("%06d", i));
statement.addBatch();
if (i % 1000 == 0) {//防止内存溢出
statement.executeBatch();
statement.clearBatch();
}
}
statement.executeBatch();
statement.close();
connection.close();
}
}
2.事务
事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部不成功。
例如:A——B 转帐,对应于如下两条 sql 语句
update account set money=money-100 where name=‘a’;
update account set money=money+100 where name=‘b’;
要保证这两句代码在任何情况下,要么一起成功要么一起失败,这时就需要使用 jdbc 事务。
当 Jdbc 程序向数据库获得一个 Connection 对象时,默认情况下这个 Connection 对象会自动向数据库提交在它上面发送的 SQL 语句。若想关闭这种默认提交方式,让多条 SQL 在一个事务中执行,可使用下列语句:
connection.setAutoCommit(false); //关闭自动提交
connection.rollback(); //回滚
connection.commit(); //提交
案例:
public static void main(String[] arg) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = null;
try {
connection = DriverManager.getConnection("jdbc:mysql:///mydb?useSSL=false"
, "root", "123456");
connection.setAutoCommit(false);
PreparedStatement statement1 = connection.prepareStatement("update user set password ='******' where id =1");
statement1.executeUpdate();
System.out.println(1 / 0);//一旦此处发生异常,则下面的语句将不再执行,程序直接跳到 catch 里面
PreparedStatement statement2 = connection.prepareStatement("update user set password ='******' where id =2");
statement2.executeUpdate();
statement1.close();
statement2.close();
connection.commit();
} catch (Exception e) {
e.printStackTrace();
connection.rollback();
} finally {
connection.close();
}
}
事务的特性
原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency)事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
隔离性(Isolation)事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
练习:
1.设计一个代码,删除表中前 10 条数据,但是删除前会在控制台弹出一个提示:是否要删除数据(Y/N)。
如果用户输入 Y,则提交。如果输入 N 则回滚。 如果输入的既不是 Y 也不是 N,则重复提示。
import j