日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

JDBC的PreparedStatement啟動(dòng)事務(wù)使用批處理executeBatch()

 沙門空海 2018-02-18

JDBC使用MySQL處理大數(shù)據(jù)的時(shí)候,自然而然的想到要使用批處理,

普通的執(zhí)行過程是:每處理一條數(shù)據(jù),就訪問一次數(shù)據(jù)庫(kù);

而批處理是:累積到一定數(shù)量,再一次性提交到數(shù)據(jù)庫(kù),減少了與數(shù)據(jù)庫(kù)的交互次數(shù),所以效率會(huì)大大提高

至于事務(wù):事務(wù)指邏輯上的一組操作,組成這組操作的各個(gè)單元,要不全部成功,要不全部不成功,默認(rèn)是關(guān)閉事務(wù)的。

              更多事務(wù)的資料,請(qǐng)參考這里:http://blog.csdn.net/caomiao2006/article/details/22412755

 

1. PreparedStatement使用批處理 executeBatch()

       1.1. 不使用executeBatch(),而使用executeUpdate()

          代碼如下:  

         Class.forName("com.mysql.jdbc.Driver");
         Connection conn = DriverManager.getConnection(dbUrl, user, password);
         PreparedStatement pstmt = conn.prepareStatement("update content set introtext=? where id=?");

         for(int i=0; i<10000; i++){
             pstmt.setString(1, "abc"+i);
             pstmt.setInt(2, id);
             pstmt.executeUpdate();
         }

         這樣,更新10000條數(shù)據(jù),就得訪問數(shù)據(jù)庫(kù)10000次

      1.2. 而使用executeBatch()

          代碼如下:

         Class.forName("com.mysql.jdbc.Driver");
         Connection conn = DriverManager.getConnection(dbUrl, user, password);
         PreparedStatement pstmt = conn.prepareStatement("update content set introtext=? where id=?");

         for(int i=0; i<10000; i++){
             pstmt.setString(1, "abc"+i);
             pstmt.setInt(2, id);
             pstmt.addBatch();//添加到同一個(gè)批處理中
         }

         pstmt.executeBatch();//執(zhí)行批處理


 

         注意:1. 如果使用了 addBatch() -> executeBatch() 還是很慢,那就得使用到這個(gè)參數(shù)了

                      rewriteBatchedStatements=true (啟動(dòng)批處理操作)

                      在數(shù)據(jù)庫(kù)連接URL后面加上這個(gè)參數(shù):      

                          String dbUrl =  "jdbc:mysql://localhost:3306/User? rewriteBatchedStatements=true";

                      2. 在代碼中,pstmt的位置不能亂放,

                          //必須放在循環(huán)體外

                     pstmt = conn.prepareStatement("update content set introtext=? where id=?");

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

                           //放這里,批處理會(huì)執(zhí)行不了,因?yàn)槊看窝h(huán)重新生成了pstmt,不是同一個(gè)了

                           //pstmt = conn.prepareStatement("update content set introtext=? where id=?");
                           pstmt.setString(1, "abc"+i);
                           pstmt.setInt(2, id);
                           pstmt.addBatch();//添加到同一個(gè)批處理中
                     }

                     pstmt.executeBatch();//執(zhí)行批處理

2. 啟用事務(wù)處理

          Class.forName("com.mysql.jdbc.Driver");

 

          Connection conn = DriverManager.getConnection(dbUrl, user, password);

          conn.setAutoCommit(false);//將自動(dòng)提交關(guān)閉
          PreparedStatement pstmt = conn.prepareStatement("update content set introtext=? where id=?");
          pstmt.setString(1, tempintrotext);
          pstmt.setInt(2, id);
          pstmt.addBatch();
          pstmt.executeBatch();
          pstmt.close();


          conn.commit();//執(zhí)行完后,手動(dòng)提交事務(wù)
          conn.setAutoCommit(true);//在把自動(dòng)提交打開
          conn.close();

3. 事務(wù)和批處理混合使用      

          Class.forName("com.mysql.jdbc.Driver");

          Connection conn = DriverManager.getConnection(dbUrl, user, password);

          conn.setAutoCommit(false);//將自動(dòng)提交關(guān)閉
          PreparedStatement pstmt = conn.prepareStatement("update content set introtext=? where id=?");

          for(int i=0; i<1000000; i++){
               pstmt.setString(1, tempintrotext);
               pstmt.setInt(2, id);
               pstmt.addBatch();

               //每500條執(zhí)行一次,避免內(nèi)存不夠的情況,可參考,Eclipse設(shè)置JVM的內(nèi)存參數(shù)

               if(i>0 && i%500==0){
                    pstmt.executeBatch();

                    //如果不想出錯(cuò)后,完全沒保留數(shù)據(jù),則可以沒執(zhí)行一次提交一次,但得保證數(shù)據(jù)不會(huì)重復(fù)

                    conn.commit();

                }

         }
          pstmt.executeBatch();//執(zhí)行最后剩下不夠500條的
          pstmt.close();

          conn.commit();//執(zhí)行完后,手動(dòng)提交事務(wù)
          conn.setAutoCommit(true);//在把自動(dòng)提交打開
          conn.close();

 較完整的代碼:

View Code

運(yùn)行結(jié)果:

   分別是: 不用批處理,不用事務(wù);

               只用批處理,不用事務(wù);

               只用事務(wù),不用批處理;

               既用事務(wù),也用批處理;(很明顯,這個(gè)最快,所以建議在處理大批量的數(shù)據(jù)時(shí),同時(shí)使用批處理和事務(wù))

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0