2015-12-02 101 views
4

我发现现有的问题similar对这个问题实际上没有明确的答案。用不同的sql查询批量准备语句

一个SQL查询一个正常批次的PreparedStatement会是这个样子:

private static void batchInsertRecordsIntoTable() throws SQLException { 

     Connection dbConnection = null; 
     PreparedStatement preparedStatement = null; 

     String insertTableSQL = "INSERT INTO DBUSER" 
       + "(USER_ID, USERNAME, CREATED_BY, CREATED_DATE) VALUES" 
       + "(?,?,?,?)"; 

     try { 
      dbConnection = getDBConnection(); 
      preparedStatement = dbConnection.prepareStatement(insertTableSQL); 

      dbConnection.setAutoCommit(false); 

      preparedStatement.setInt(1, 101); 
      preparedStatement.setString(2, "mkyong101"); 
      preparedStatement.setString(3, "system"); 
      preparedStatement.setTimestamp(4, getCurrentTimeStamp()); 
      preparedStatement.addBatch(); 

      preparedStatement.setInt(1, 102); 
      preparedStatement.setString(2, "mkyong102"); 
      preparedStatement.setString(3, "system"); 
      preparedStatement.setTimestamp(4, getCurrentTimeStamp()); 
      preparedStatement.addBatch(); 

      preparedStatement.setInt(1, 103); 
      preparedStatement.setString(2, "mkyong103"); 
      preparedStatement.setString(3, "system"); 
      preparedStatement.setTimestamp(4, getCurrentTimeStamp()); 
      preparedStatement.addBatch(); 

      preparedStatement.executeBatch(); 

      dbConnection.commit(); 

      System.out.println("Record is inserted into DBUSER table!"); 

     } catch (SQLException e) { 

      System.out.println(e.getMessage()); 
      dbConnection.rollback(); 

     } finally { 

      if (preparedStatement != null) { 
       preparedStatement.close(); 
      } 

      if (dbConnection != null) { 
       dbConnection.close(); 
      } 

     } 

    } 

来自http://www.mkyong.com/jdbc/jdbc-preparedstatement-example-batch-update/

不过,我正在寻找对进行批量交易的方式不同的 sql查询。即INSERT INTO TABLE AINSERT INTO TABLE B,没有SQL注入攻击的风险。我知道preparedstatements是避免这种攻击的首选方法,但我不知道用于区分SQL查询的批量事务的方法吗?

回答

6

两(2)不同的SQL查询,则需要两(2)不同PreparedStatement对象和每个人都会有自己的一批,但是当你想将查询发送到服务器,你可以简单地执行每批次:

try (
     PreparedStatement thisPs = conn.prepareStatement("INSERT INTO thisTable (thisId, thisText) VALUES (?,?)"); 
     PreparedStatement thatPs = conn.prepareStatement("INSERT INTO thatTable (thatId, thatText) VALUES (?,?)")) { 

    thisPs.setInt(1, 1); 
    thisPs.setString(2, "thisText1"); 
    thisPs.addBatch(); 

    thatPs.setInt(1, 1); 
    thatPs.setString(2, "thatText1"); 
    thatPs.addBatch(); 

    thisPs.setInt(1, 2); 
    thisPs.setString(2, "thisText2"); 
    thisPs.addBatch(); 

    thatPs.setInt(1, 2); 
    thatPs.setString(2, "thatText2"); 
    thatPs.addBatch(); 

    thisPs.executeBatch(); 
    thatPs.executeBatch(); 
} 

此外,请注意术语。谈“间歇事务”是有些模糊:

  • addBatchexecuteBatch是所述机构多个语句发送到服务器作为单个批次(传输)的一部分。这会影响数据库服务器发送(传输)到报表的方式

  • 数据库事务是由此许多语句将被处理作为一个完整的组,即,机构,无论是整个组将被处理(“定向的”)或整个组将是丢弃(“回滚”)。 Connection#setAutoCommit()Connection#commit()Connection#rollback()方法控制此行为。这会影响数据库服务器执行的报表的执行方式

+1

我知道可以创建多个实例,但是如果所有查询都不同,那么这将不会增加任何性能优势。我最终只是提到SQL注入安全性,并使用常规批处理语句而不是预处理语句。 – Hooli