乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Java JDBC批處理插入數(shù)據(jù)操作

       某某某1014 2014-01-07

      在此筆記里,我們將看到我們?nèi)绾慰梢允褂孟馭tatement和PreparedStatement JDBC API來批量在任何數(shù)據(jù)庫中插入數(shù)據(jù)。此外,我們將努力探索一些場景,如在內(nèi)存不足時正常運(yùn)行,以及如何優(yōu)化批量操作。

      首先,使用Java JDBC基本的API批量插入數(shù)據(jù)到數(shù)據(jù)庫中。

      Simple Batch - 簡單批處理
          我把它叫做簡單批處理。要求很簡單,執(zhí)行批量插入列表,而不是為每個INSERT語句每次提交數(shù)據(jù)庫,我們將使用JDBC批處理操作和優(yōu)化性能。

      想想一下下面的代碼:

      Bad Code
       String [] queries = {
          "insert into employee (name, city, phone) values ('A', 'X', '123')",
          "insert into employee (name, city, phone) values ('B', 'Y', '234')",
          "insert into employee (name, city, phone) values ('C', 'Z', '345')",
       };
      Connection connection = new getConnection();
      Statement statemenet = connection.createStatement();
       for (String query : queries) {
          statemenet.execute(query);
      }
      statemenet.close();
      connection.close();

      這是糟糕的代碼。它單獨(dú)執(zhí)行每個查詢,每個INSERT語句的都提交一次數(shù)據(jù)庫??紤]一下,如果你要插入1000條記錄呢?這是不是一個好主意。

      下面是執(zhí)行批量插入的基本代碼。來看看:

      Good Code

      Connection connection = new getConnection();
      Statement statemenet = connection.createStatement();
       for (String query : queries) {
          statemenet.addBatch(query);
      }
      statemenet.executeBatch();
      statemenet.close();
      connection.close();

       

      請注意我們?nèi)绾问褂胊ddBatch()方法,而不是直接執(zhí)行查詢。然后,加入所有的查詢,我們使用statement.executeBatch()方法一次執(zhí)行他們。沒有什么花哨,只是一個簡單的批量插入。

      請注意,我們已經(jīng)從一個String數(shù)組構(gòu)建了查詢?,F(xiàn)在,你可能會想,使其動態(tài)化。例如:

      import java.sql.Connection;
      import java.sql.Statement;
      //...
      Connection connection = new getConnection();
      Statement statemenet = connection.createStatement();
      for (Employee employee: employees) {
          String query = "insert into employee (name, city) values('"
                  + employee.getName() + "','" + employee.getCity + "')";
          statemenet.addBatch(query);
      }
      statemenet.executeBatch();
      statemenet.close();
      connection.close();

      請注意我們是如何從Employee對象中的數(shù)據(jù)動態(tài)創(chuàng)建查詢并在批處理中添加,插入一氣呵成。完美!是不是?

      等等......你必須思考什么關(guān)于SQL注入?這樣動態(tài)創(chuàng)建的查詢SQL注入是很容易的。并且每個插入查詢每次都被編譯。

      為什么不使用PreparedStatement而不是簡單的聲明。是的,這是個解決方案。下面是SQL注入安全批處理。

      SQL Injection Safe Batch - SQL注入安全批處理
      思考一下下面代碼:

      import java.sql.Connection;
      import java.sql.PreparedStatement;
       //...
      String sql = "insert into employee (name, city, phone) values (?, ?, ?)";
      Connection connection = new getConnection();
      PreparedStatement ps = connection.prepareStatement(sql);
       for (Employee employee: employees) {
          ps.setString(1, employee.getName());
          ps.setString(2, employee.getCity());
          ps.setString(3, employee.getPhone());
          ps.addBatch();
      }
      ps.executeBatch();
      ps.close();
      connection.close();
      

      看看上面的代碼。漂亮。我們使用的java.sql.PreparedStatement和在批處理中添加INSERT查詢。這是你必須實(shí)現(xiàn)批量插入邏輯的解決方案,而不是上述Statement那個。

      這一解決方案仍然存在一個問題??紤]這樣一個場景,在您想要插入到數(shù)據(jù)庫使用批處理上萬條記錄。嗯,可能產(chǎn)生的OutOfMemoryError:

      java.lang.OutOfMemoryError: Java heap space
      com.mysql.jdbc.ServerPreparedStatement$BatchedBindValues.<init>(ServerPreparedStatement.java:72)
      com.mysql.jdbc.ServerPreparedStatement.addBatch(ServerPreparedStatement.java:330)
      org.apache.commons.dbcp.DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:171)

      這是因?yàn)槟阍噲D在一個批次添加所有語句,并一次插入。最好的辦法是將執(zhí)行分批次??纯聪旅娴慕鉀Q方案

      Smart Insert: Batch within Batch - 智能插入:將整批分批
      這是一個簡單的解決方案??紤]批量大小為1000,每1000個查詢語句為一批插入提交。

      String sql = "insert into employee (name, city, phone) values (?, ?, ?)";
      Connection connection = new getConnection();
      PreparedStatement ps = connection.prepareStatement(sql);
      final int batchSize = 1000;
      int count = 0;
      for (Employee employee: employees) {
          ps.setString(1, employee.getName());
          ps.setString(2, employee.getCity());
          ps.setString(3, employee.getPhone());
          ps.addBatch();
          if(++count % batchSize == 0) {
              ps.executeBatch();
          }
      }
      ps.executeBatch(); // insert remaining records
      ps.close();
      connection.close();

      這才是理想的解決方案,它避免了SQL注入和內(nèi)存不足的問題??纯次覀?nèi)绾芜f增計(jì)數(shù)器計(jì)數(shù),一旦BATCHSIZE 達(dá)到 1000,我們調(diào)用executeBatch()提交。

      來源: http://itindex.blog.51cto.com/3619105/801447

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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多