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 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的要快一下。