1. 程式人生 > >JDBC從入門到放棄-06:JDBC的批處理

JDBC從入門到放棄-06:JDBC的批處理

JDBC從入門到放棄

06-JDBC的批處理

當有成批插入或者更新記錄的需求時,可以採用JDBC的批量更新機制,這一機制允許多條語句一次性的提交給資料庫批量處理。通常情況下比單獨處理要更有效率。

批量處理一般流程。

假設我們有100000條資料要插入的資料庫,採用批處理,每10000條批量插入一次。

①先不執行sql,可以積累起來,每10000條執行一次

stat.addBatch(); // 積累起來, 暫時不執行

if(i%10000==0) {

stat.executeBatch(); //批量處理

stat.clearBatch(); //清空前面的等待sql的記錄

}

②//sql總條數不是批量的整數倍,迴圈外面,還要在執行一次

if(100000%10000!=0) {

stat.executeBatch(); //批量處理

stat.clearBatch(); //清空前面的等待sql的記錄

}

下面我們來演示批處理的處理。

分別採用statement和preparedStatement以及批處理來進行插入,我們測試一下每種操作執行的總時間。

為了測試結果的準確性,我們新建一張表,每次操作之前,清空表中的資料。

delete from testbatchuser;

採用statement進行插入

     /**

      * 測試statement不使用Batch的情況下進行大量資料插入

      */

     @Test

     public void testNoBatchStatement() {

          long start = System.currentTimeMillis();

          Connection con = null;

          Statement statement = null;

          try {

               // 1:獲取資料庫里歐按揭

               con = DBUtils.getConnection();

               for

(int i = 0;i<100000;i++) {

                    String userName= "使用者:"+i;

                    int age = i;

                    // 2:準備插入資料庫語句

                    String sql = "INSERT INTO testbatchuser(name,age)" + " VALUES('" + userName + "'," + age +");";

                    // 3:執行資料庫插入語句

                    statement = con.createStatement();

                    statement.executeUpdate(sql);

               }

          } catch (SQLException e) {

               // TODO Auto-generated catch block

               e.printStackTrace();

          }finally {

               DBUtils.close(con, statement, null);

          }

          long end = System.currentTimeMillis();

          System.out.println("總耗時:"+(end-start)+"ms");

     }

總耗時:804887ms

採用preparedStatement進行插入

     /**

      * 測試statement不使用Batch的情況下進行大量資料插入

      */

     @Test

     public void testNoBatchPreparedStatement() {

          long start = System.currentTimeMillis();

          Connection con = null;

          PreparedStatement pst = null;

          try {

               // 1:獲取資料庫里歐按揭

               con = DBUtils.getConnection();

               // 2:準備插入資料庫語句

               String sql ="INSERT INTO testbatchuser(name,age)" + " VALUES(?,?);";

               pst = con.prepareStatement(sql);

               for(int i = 0;i<100000;i++) {

                    String userName= "使用者:"+i;

                    int age = i;

                    pst.setString(1, userName);

                    pst.setInt(2, age);

                    // 3:執行資料庫插入語句

                    pst.executeUpdate();

               }

          } catch (SQLException e) {

               // TODO Auto-generated catch block

               e.printStackTrace();

          }finally {

               DBUtils.close(con, pst, null);

          }

          long end = System.currentTimeMillis();

          System.out.println("總耗時:"+(end-start)+"ms");

     }

總耗時:799335ms

採用batch批量進行插入

     /**

      * 測試preparedstatement使用Batch的情況下進行大量資料插入

      */

     @Test

     public void testBatchPreparedStatement() {

          long start = System.currentTimeMillis();

          Connection con = null;

          PreparedStatement pst = null;

          try {

               // 1:獲取資料庫里歐按揭

               con = DBUtils.getConnection();

               // 2:準備插入資料庫語句

               String sql ="INSERT INTO testbatchuser(name,age)" + " VALUES(?,?);";

               pst = con.prepareStatement(sql);

               int totleLength = 100000;

               int stepLenth =10000;

               for(int i = 1;i<totleLength+1;i++) {

                    String userName= "使用者:"+(i-1);

                    int age = i-1;

                    pst.setString(1, userName);

                    pst.setInt(2, age);

                    pst.addBatch();// 把每一條不一樣的sql暫存起來

                    if(i%stepLenth==0) {//先不執行sql,可以積累起來,stepLenth條執行一次

                         // 3:執行資料庫插入語句

                         pst.executeBatch();

                         pst.clearBatch(); //清空前面的等待sql的記錄

                    }

               }

               if(totleLength%stepLenth!=0) {

                    pst.executeBatch(); //批量處理

                    pst.clearBatch(); //清空前面的等待sql的記錄

               }

          } catch (SQLException e) {

               // TODO Auto-generated catch block

               e.printStackTrace();

          }finally {

               DBUtils.close(con, pst, null);

          }

          long end = System.currentTimeMillis();

          System.out.println("總耗時:"+(end-start)+"ms");

     }

檢視插入結果,結果正確。

總耗時:774841ms

在本機上測試,從結果上看,批量插入比preparedStatement的和Statement的要快一下。