五月综合缴情婷婷六月,色94色欧美sute亚洲线路二,日韩制服国产精品一区,色噜噜一区二区三区,香港三级午夜理伦三级三

您現(xiàn)在的位置: 365建站網(wǎng) > 365文章 > JDBC的批量操作executeBatch() 批量執(zhí)行Sql語句

JDBC的批量操作executeBatch() 批量執(zhí)行Sql語句

文章來源:365jz.com     點擊數(shù):2422    更新時間:2018-05-30 16:02   參與評論
JDBC提供了數(shù)據(jù)庫batch處理的能力,在數(shù)據(jù)大批量操作(新增、刪除等)的情況下可以大幅度提升系統(tǒng)的性能。我以前接觸的一個項目,在沒有采用batch處理時,刪除5萬條數(shù)據(jù)大概要半個小時左右,后來對系統(tǒng)進行改造,采用了batch處理的方式,刪除5萬條數(shù)據(jù)基本上不會超過1分鐘??匆欢蜫DBC代碼:

// 關(guān)閉自動執(zhí)行
con.setAutoCommit(false);
Statement stmt = con.createStatement();

stmt.addBatch("INSERT INTO employees VALUES (1000, 'Joe Jones')");
stmt.addBatch("INSERT INTO departments VALUES (260, 'Shoe')");
stmt.addBatch("INSERT INTO emp_dept VALUES (1000, 260)");

// 提交一批要執(zhí)行的更新命令
int[] updateCounts = stmt.executeBatch();

    本例中禁用了自動執(zhí)行模式,從而在調(diào)用 Statement.executeBatch() 時可以防止 JDBC 執(zhí)行事務(wù)處理。禁用自動執(zhí)行使得應(yīng)用程序能夠在發(fā)生錯誤及批處理中的某些命令不能執(zhí)行時決定是否執(zhí)行事務(wù)處理。因此,當(dāng)進行批處理更新時,通常應(yīng)該關(guān)閉自動執(zhí)行。

    在JDBC 2.0 中,Statement 對象能夠記住可以一起提交執(zhí)行的命令列表。創(chuàng)建語句時,與它關(guān)聯(lián)的命令列表為空。Statement.addBatch() 方法為調(diào)用語句的命令列表添加一個元素。如果批處理中包含有試圖返回結(jié)果集的命令,則當(dāng)調(diào)用 Statement. executeBatch() 時,將拋出 SQLException。只有 DDL 和 DML 命令(它們只返回簡單的更新計數(shù))才能作為批處理的一部分來執(zhí)行。如果應(yīng)用程序決定不提交已經(jīng)為某語句構(gòu)
造的命令批處理,則可以調(diào)用方法 Statement.clearBatch()(以上沒有顯示)來重新設(shè)置批處理。

    Statement.executeBatch() 方法將把命令批處理提交給基本 DBMS 來執(zhí)行。命令的執(zhí)行將依照在批處理中的添加順序來進行。ExecuteBatch() 為執(zhí)行的命令返回更新計數(shù)數(shù)組。數(shù)組中對應(yīng)于批處理中的每個命令都包含了一項,而數(shù)組中各元素依據(jù)命令的執(zhí)行順序(這還是和命令的最初添加順序相同)來排序。調(diào)用executeBatch() 將關(guān)閉發(fā)出調(diào)用的 Statement 對象的當(dāng)前結(jié)果集(如果有一個結(jié)果集是打開的)。executeBatch() 返回后,將重新將語句的內(nèi)部批處理命令列表設(shè)置為空。

    如果批處理中的某個命令無法正確執(zhí)行,則 ExecuteBatch() 將拋出BatchUpdateException。可以調(diào)用BatchUpdateException.getUpdateCounts() 方法來為批處理中成功執(zhí)行的命令返回更新計數(shù)的整型數(shù)組。因為當(dāng)有第一個命令返回錯誤時,Statement.executeBatch() 就中止,而且這些命令是依據(jù)它們在批處理中的添加順序而執(zhí)行的。所以如果 BatchUpdateException.getUpdateCounts() 所返回的數(shù)組包含 N 個元素,這就意味著在調(diào)用 executeBatch() 時批處理中的前 N 個命令被成功執(zhí)行。用PreparedStatement 可以象下面這樣寫代碼:


// 關(guān)閉自動執(zhí)行
con.setAutoCommit(false);
PreparedStatement stmt = con.prepareStatement("INSERT INTO employees VALUES (?, ?)");

stmt.setInt(1, 2000);
stmt.setString(2, "Kelly Kaufmann");
stmt.addBatch();

// 提交要執(zhí)行的批處理
int[] updateCounts = stmt.executeBatch();

========================================

PrepareStatement 也是接口
PrepareStatement extends Statement
PrepareStatement 本身沒有 int[] executeBatch() throws SQLException 方法
而是繼承了Statement的方法,且它們都是接口沒有實際實現(xiàn)方法,但Statement
接口對executeBatch()方法做了規(guī)范
/**
     * Submits a batch of commands to the database for execution and
     * if all commands execute successfully, returns an array of update counts.
       每次提交一批命令到數(shù)據(jù)庫中執(zhí)行,如果所有的命令都成功執(zhí)行了,那么返回一個
       數(shù)組,這個數(shù)組是說明每條命令所影響的行數(shù)
     * The <code>int</code> elements of the array that is returned are ordered
     * to correspond to the commands in the batch, which are ordered
     * according to the order in which they were added to the batch.
       返回的數(shù)組中每個整型值都是排過序的,它們的順序和批量處理中的命令們是一致的,
       命令的順序是按照它們被加到批處理中的順序一致。
     * The elements in the array returned by the method <code>executeBatch</code>
     * may be one of the following:
       executeBatch方法返回的數(shù)組中的元素可能是下面幾種情形之一:
     * <OL>
     * <LI>A number greater than or equal to zero -- indicates that the
     * command was processed successfully and is an update count giving the
     * number of rows in the database that were affected by the command's
     * execution
       一個大于或等于零的數(shù)字,簡單說來命令成功執(zhí)行后就返回它所影響到的行的數(shù)目
     * <LI>A value of <code>SUCCESS_NO_INFO</code> -- indicates that the command was
     * processed successfully but that the number of rows affected is
     * unknown
       
      * The constant indicating that a batch statement executed successfully
      * but that no count of the number of rows it affected is available.
      int SUCCESS_NO_INFO = -2;
      常量SUCCESS_NO_INFO代表的值=-2,也就是說命令執(zhí)行成功了但命令影響到的行數(shù)
      無法統(tǒng)計,是未知的,只能返回SUCCESS_NO_INFO來說明命令執(zhí)行情況。
     * <P> * If one of the commands in a batch update fails to execute properly,
     * this method throws a <code>BatchUpdateException</code>, and a JDBC
     * driver may or may not continue to process the remaining commands in
     * the batch.
       如果批量處理時其中一個命令執(zhí)行失敗,則會拋出一個異常BatchUpdateException
       JDBC驅(qū)動可能會停止剩余的命令,也可能繼續(xù)執(zhí)行剩余的命令。
     * However, the driver's behavior must be consistent with a
     * particular DBMS, either always continuing to process commands or never
     * continuing to process commands.
       不管怎樣,驅(qū)動要怎么做取決于數(shù)據(jù)庫管理系統(tǒng)的細節(jié),總是執(zhí)行或總是不執(zhí)行兩者其一。
     * If the driver continues processing
     * after a failure, the array returned by the method
     * <code>BatchUpdateException.getUpdateCounts</code>
     * will contain as many elements as there are commands in the batch, and
     * at least one of the elements will be the following:
       發(fā)生失敗后如果驅(qū)動繼續(xù)執(zhí)行,通過BatchUpdateException.getUpdateCounts()方法返回
       的數(shù)組應(yīng)該包括批處理中有的那些命令的結(jié)果,并且至少有一個元素的值是下面的情況:
     * <P>
     * <LI>A value of <code>EXECUTE_FAILED</code> -- indicates that the command failed
     * to execute successfully and occurs only if a driver continues to
     * process commands after a command fails
           int EXECUTE_FAILED = -3;
           指示命令沒有成功執(zhí)行的常量值EXECUTE_FAILED,并且只有在命令出錯后驅(qū)動繼續(xù)執(zhí)行的情況下才會出現(xiàn),
           如果出錯后不再執(zhí)行,則返回的結(jié)果中沒有錯誤信息只有那些被成功執(zhí)行后的結(jié)果。
     * </OL>
     * <P> * A driver is not required to implement this method.
     * The possible implementations and return values have been modified in
     * the Java 2 SDK, Standard Edition, version 1.3 to
     * accommodate the option of continuing to proccess commands in a batch
     * update after a <code>BatchUpdateException</code> obejct has been thrown.
       驅(qū)動不實現(xiàn)此方法,可能會出現(xiàn)的實現(xiàn)和返回值在Java 2 SDK,Standard Edition,
       version 1.3 ,以適應(yīng)批處理時拋出BatchUpdateException 異常后是繼續(xù)執(zhí)行還是
       終止執(zhí)行的選項。
      
     * @return an array of update counts containing one element for each
     * command in the batch. The elements of the array are ordered according
     * to the order in which commands were added to the batch.
       返回一個和添加命令時的順序一樣的數(shù)組結(jié)果
     * @exception SQLException if a database access error occurs or the
     * driver does not support batch statements. Throws {@link BatchUpdateException}
     * (a subclass of <code>SQLException</code>) if one of the commands sent to the
     * database fails to execute properly or attempts to return a result set.
     * @since 1.3
     */
       如果數(shù)據(jù)庫訪問異?;蝌?qū)動不支持批處理命令,或者如果一個命令發(fā)送到數(shù)據(jù)庫時失敗或嘗試取得結(jié)果集
       時失敗,都會拋一個異常BatchUpdateException 它是SQLException的子類。


executeBatch()方法:用于成批地執(zhí)行SQL語句,但不能執(zhí)行返回值是ResultSet結(jié)果集的SQL語句,而是直接執(zhí)行stmt.executeBatch(); 
addBatch():向批處理中加入一個更新語句。 
clearBatch():清空批處理中的更新語句


 public void executeBatch() throws SQLException {
            Connection con = Toolkit. getMySqlConnection();
            String sql = "xxx";
            String sql_2 = "xxx";

            Statement st = null;
           // Statement、PreparedStatement(它從 Statement 繼承而來)和CallableStatement(它從 PreparedStatement 繼承而來)。它們都專用于發(fā)送特定類型的 SQL 語句:Statement 對象用于執(zhí)行不帶參數(shù)的簡單 SQL 語句;PreparedStatement 對象用于執(zhí)行帶或不帶 IN參數(shù)的預(yù)編譯 SQL 語句;CallableStatement 對象用于執(zhí)行對數(shù)據(jù)庫已存儲過程的調(diào)用。
             try {
                   st = con.createStatement();

                   //conn.setAutoCommit()的功能是每執(zhí)行一條SQL語句,就作為一次事務(wù)提交。但一般在項目中很有可能需要執(zhí)行多條SQL語句作為一個事務(wù)。若有一個執(zhí)行不成功,就會rollback();當(dāng)true的時候可啟用自動提交模式,false可禁用該模式
                   con.setAutoCommit(false);
                   //使用addBatch()添加SQL語句
                   st.addBatch(sql);
                   st.addBatch(sql_2);
                   st.addBatch(....);
                //使用executeBatch()執(zhí)行批量sql語句
                   st.executeBatch();
                   con.commit();
            } catch (SQLException e) {
                   loger.info(e.getMessage());
            } finally {
                  Toolkit. close(con);
                  st.close();
            }
      }

實現(xiàn)批處理addBatch,executeBatch

l業(yè)務(wù)場景:當(dāng)需要向數(shù)據(jù)庫發(fā)送一批SQL語句執(zhí)行時,應(yīng)避免向數(shù)據(jù)庫一條條的發(fā)送執(zhí)行,而應(yīng)采用JDBC的批處理機制,以提升執(zhí)行效率。
l實現(xiàn)批處理有兩種方式,第一種方式:
•Statement.addBatch(sql)
l執(zhí)行批處理SQL語句
•executeBatch()方法:執(zhí)行批處理命令
•clearBatch()方法:清除批處理命令


Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtil.getConnection();
String sql1 = "insert into user(name,password,email,birthday)
  values('kkk','123','abc@sina.com','1978-08-08')";
String sql2 = "update user set password='123456' where id=3";
st = conn.createStatement();
st.addBatch(sql1);  //把SQL語句加入到批命令中
st.addBatch(sql2);  //把SQL語句加入到批命令中
st.executeBatch();
} finally{
  JdbcUtil.free(conn, st, rs);
}


l采用Statement.addBatch(sql)方式實現(xiàn)批處理:
•優(yōu)點:可以向數(shù)據(jù)庫發(fā)送多條不同的SQL語句。
•缺點:
•SQL語句沒有預(yù)編譯。
•當(dāng)向數(shù)據(jù)庫發(fā)送多條語句相同,但僅參數(shù)不同的SQL語句時,需重復(fù)寫上很多條SQL語句。例如:
  Insert into user(name,password) values(‘aa’,’111’);
  Insert into user(name,password) values(‘bb’,’222’);
  Insert into user(name,password) values(‘cc’,’333’);
  Insert into user(name,password) values(‘dd’,’444’);


l實現(xiàn)批處理的第二種方式:
•PreparedStatement.addBatch()
conn = JdbcUtil.getConnection();
String sql = "insert into user(name,password,email,birthday) values(?,?,?,?)";
st = conn.prepareStatement(sql);
for(int i=0;i<50000;i++){
st.setString(1, "aaa" + i);
st.setString(2, "123" + i);
st.setString(3, "aaa" + i + "@sina.com");
st.setDate(4,new Date(1980, 10, 10));
st.addBatch();
if(i%1000==0){
st.executeBatch();
st.clearBatch();
}
}
st.executeBatch();
l采用PreparedStatement.addBatch()實現(xiàn)批處理
•優(yōu)點:發(fā)送的是預(yù)編譯后的SQL語句,執(zhí)行效率高。
•缺點:只能應(yīng)用在SQL語句相同,但參數(shù)不同的批處理中。因此此種形式的批處理經(jīng)常用于在同一個表中批量插入數(shù)據(jù),或批量更新表的數(shù)據(jù)。

如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會為你解答??! 點擊進入論壇

發(fā)表評論 (2422人查看0條評論)
請自覺遵守互聯(lián)網(wǎng)相關(guān)的政策法規(guī),嚴禁發(fā)布色情、暴力、反動的言論。
昵稱:
最新評論
------分隔線----------------------------

其它欄目

· 建站教程
· 365學(xué)習(xí)

業(yè)務(wù)咨詢

· 技術(shù)支持
· 服務(wù)時間:9:00-18:00
365建站網(wǎng)二維碼

Powered by 365建站網(wǎng) RSS地圖 HTML地圖

copyright © 2013-2024 版權(quán)所有 鄂ICP備17013400號