day47-JDBC和连接池03( 二 )

  • clearBatch():清空批处理包的语句
  • JDBC连接MySQL时,如果要使用批处理功能,请在url中加参数?rewriteBatchedStatements=true
  • 批处理往往和PreparedStatement一起搭配使用,可以既减少编译次数,又减少运行次数,效率大大提高
  • 9.1批处理应用
    例子
    1. 演示向admin2表中添加5000条数据,看看使用批处理耗时多久
    2. 注意批处理需要修改配置文件的数据:url=jdbc:mysql://localhost:3306/数据库?rewriteBatchedStatements=true
    user=rootpassword=123456url=jdbc:mysql://localhost:3306/hsp_db02?rewriteBatchedStatements=truedriver=com.mysql.jdbc.Driver首先创建测试表admin2
    CREATE TABLE admin2( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(32) NOT NULL, PASSWORD VARCHAR(32) NOT NULL );SELECT COUNT(*) FROM admin2;测试程序:
    package li.jdbc.batch_;import li.jdbc.utils.JDBCUtils;import org.junit.Test;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;/** * 演示java的批处理 */public class Batch_ {//传统方法,添加5000条数据到admin2@Testpublic void noBatch() throws Exception {//获取连接Connection connection = JDBCUtils.getConnection();//sqlString 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);}//使用批量方式添加数据--注意在配置文件添加参数?rewriteBatchedStatements=true@Testpublic void batch() throws Exception {//获取连接Connection connection = JDBCUtils.getConnection();//sqlString 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条SQL时,再批量执行if ((i + 1) % 1000 == 0) {//每满1000条时 , 就批量执行preparedStatement.executeBatch();//执行完就清空批处理包preparedStatement.clearBatch();}}long end = System.currentTimeMillis();System.out.println("批量方式耗时:" + (end - start));//关闭连接JDBCUtils.close(null, preparedStatement, connection);}}
    day47-JDBC和连接池03

    文章插图
    day47-JDBC和连接池03

    文章插图
    day47-JDBC和连接池03

    文章插图
    9.2批处理源码分析在上述代码中 , 在preparedStatement.addBatch();语句旁打上断点,点击debug,点击step into
    day47-JDBC和连接池03

    文章插图
    可以看到光标跳转到了如下方法:
    public void addBatch() throws SQLException {if (this.batchedArgs == null) {this.batchedArgs = new ArrayList();}this.batchedArgs.add(new PreparedStatement.BatchParams(this.parameterValues, this.parameterStreams, this.isStream, this.streamLengths, this.isNull));}第一次执行该方法时,会创建Arraylist类型的对象集合elementDate=>Object[] , elementDate=>Object[]用来存放我们预处理的SQL语句 。当elementDate满后,就按照1.5倍扩容
    当添加到指定的值后,就会执行executeBatch();
    批处理会减少我们发送SQL语句的网络开销,并且减少编译次数,因此效率提高了
    1.5倍扩容:
    day47-JDBC和连接池03

    文章插图
    day47-JDBC和连接池03

    文章插图
    9.3.事务和批处理的区别
    • 事务:事务底层是在数据库方存储SQL,没有提交事务的数据放在数据库的临时表空间 。最后一次提交是把临时表空间的数据提交到数据库服务器执行事务消耗的是数据库服务器内存
    • 批处理:
      批处理底层是在客户端存储SQL最后一次执行批处理是把客户端存储的数据发送到数据库服务器执行 。批处理消耗的是客户端的内存

    推荐阅读