Java JDBC批量執行executeBatch方法詳解

JDBC事務

在數據庫中,所謂事務是指一組邏輯操作單元,使數據從一種狀態變換到另一種狀態。為確保數據庫中數據的一致性,數據的操縱應當是離散的成組的邏輯單元:當它全部完成時,數據的一致性可以保持,而當這個單元中的一部分操作失敗,整個事務應全部視為錯誤,所有從起始點以後的操作應全部回退到開始狀態。

事務的操作:先定義開始一個事務,然後對數據作修改操作,這時如果提交(COMMIT),這些修改就永久地保存下來,如果回退(ROLLBACK),數據庫管理系統將放棄您所作的所有修改而回到開始事務時的狀態。

事務的ACID屬性

1. 原子性(Atomicity)
原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。 

2. 一致性(Consistency)
事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態。(數據不被破壞)

3. 隔離性(Isolation)
事務的隔離性是指一個事務的執行不能被其他事務幹擾,即一個事務內部的操作及使用的數據對並發的其他事務是隔離的,並發執行的各個事務之間不能互相幹擾。

4. 持久性(Durability)

持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來的其他操作和數據庫故障不應該對其有任何影響。

在JDBC中,事務默認是自動提交的,每次執行一個 SQL 語句時,如果執行成功,就會向數據庫自動提交,而不能回滾

為瞭讓多個 SQL 語句作為一個事務執行:

  1. 執行語句前調用 Connection 對象的 setAutoCommit(false); 以取消自動提交事務
  2. 在所有的 SQL 語句都成功執行後,調用 commit(); 方法提交事務
  3. 在出現異常時,調用 rollback(); 方法回滾事務。

JDBC批量執行

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

JDBC的批量處理語句包括下面兩個方法:

addBatch(String):添加需要批量處理的SQL語句或是參數;

executeBatch();執行批量處理語句;

clearBatch();清除批量打包

通常我們會遇到兩種批量執行SQL語句的情況:

多條SQL語句的批量處理;

for (int i = 1; i < 5000; i++) {
    sql = "insert into person(id,name,email) values(" + i",'name" + i + "','email" + i + "')";
    stmt.addBatch(sql);
    if((i+1)%1000==0){
        //批量處理
        stmt.executeBatch();
        //清除stmt中積攢的參數列表
        stmt.clearBatch();
    }
}

一個SQL語句的批量傳參;

for(int i=1;i<100000;i++){
    pstmt.setInt(1, i);
    pstmt.setString(2, "name"+i);
    pstmt.setString(3, "email"+i);
    pstmt.addBatch();
    if((i+1)%1000==0){
        //批量處理
        pstmt.executeBatch();
        //清空pstmt中積攢的sql
        pstmt.clearBatch();
    }
}

JDBC執行SQL語句,有兩個處理的接口,一個PreparedStatement,Statement,一般操作JDBC比較用得多的還是PreparedStatement

不過在執行批量,PreparedStatement有點不夠Statement

ps = conn.prepareStatement(sql);
for(int i = 0;i<10;i++){
    ps.setString(1,"1");
    //PreparedStatement批處理方式一
    ps.addBatch();
}
//PreparedStatement批處理方式二
ps.addBatch("靜態SQL");
ps.executeBatch();

這個是正常執行的

可是把PreparedStatement放到裡面就沒效瞭,以下:

for(int i = 0;i<10;i++){
   ps = conn.prepareStatement(sql);
   ps.setString(1,"1");
   ps.addBatch();
}
ps.executeBatch();

Statement適合循環賦值到sql,代碼以下:

Statement st = conn.createStatement();

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

   st.addBatch("靜態sql..........");

}

st.executeBatch();

這個是正常執行所有的語句

總結:造成這樣的原因是

Statement st = conn.createStatement();這裡可以不放SQL語句

ps = conn.prepareStatement(sql);這個一定要放初始SQL語句

JDBC的批處理不能加入select語句,否則會拋異常:

java.sql.BatchUpdateException: Can not issue SELECT via executeUpdate(). 
at com.MySQL.jdbc.StatementImpl.executeBatch(StatementImpl.java:1007)

到此這篇關於Java JDBC批量執行executeBatch方法詳解的文章就介紹到這瞭,更多相關Java JDBC批量執行executeBatch內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: