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最后一次執行批處理是把客戶端存儲的數據發送到數據庫服務器執行 。批處理消耗的是客戶端的內存

    推薦閱讀