используя JDBC prepareStatement в пакете - PullRequest
17 голосов
/ 28 июля 2011

Я использую партии Statement s для запроса моей базы данных. Сейчас я провел некоторое исследование, и я хочу переписать свое приложение, чтобы использовать вместо него preparedStatement, но мне трудно разобраться, как добавить запросы в preparedStatement пакет.

Вот что я делаю сейчас:

private void addToBatch(String sql) throws SQLException{
sttmnt.addBatch(sql);
batchSize++;
if (batchSize == elementsPerExecute){
    executeBatches();
}
}

где sttmnt является членом класса типа Statement.

То, что я хочу сделать, это использовать preparedStatement метод setString(int, String), чтобы установить некоторые динамические данные, а затем добавить их в пакет.

К сожалению, я не до конца понимаю, как это работает и как я могу использовать setString(int, String) для определенного sql в пакете ИЛИ создать новый preparedStatemnt для каждого имеющегося sql, а затем объединить их всех в один пакет .

возможно ли это сделать? или я действительно что-то упускаю в моем понимании preparedStatement?

Ответы [ 3 ]

18 голосов
/ 28 июля 2011

Прочтите раздел 6.1.2 этого документа для примеров. В основном вы используете один и тот же объект оператора и вызываете пакетный метод после того, как все заполнители установлены. Другой пример IBM DB2 , который должен работать для любой реализации JDBC. Со второго сайта:

try {
  connection con.setAutoCommit(false);        
  PreparedStatement prepStmt = con.prepareStatement(    
    "UPDATE DEPT SET MGRNO=? WHERE DEPTNO=?");
  prepStmt.setString(1,mgrnum1);            
  prepStmt.setString(2,deptnum1);
  prepStmt.addBatch();                      

  prepStmt.setString(1,mgrnum2);                        
  prepStmt.setString(2,deptnum2);
  prepStmt.addBatch();
  int [] numUpdates=prepStmt.executeBatch();
  for (int i=0; i < numUpdates.length; i++) {
    if (numUpdates[i] == -2)
      System.out.println("Execution " + i + 
        ": unknown number of rows updated");
    else
      System.out.println("Execution " + i + 
        "successful: " + numUpdates[i] + " rows updated");
  }
  con.commit();
} catch(BatchUpdateException b) {
  // process BatchUpdateException
} 
6 голосов
/ 28 июля 2011

С PreparedStatement вы можете использовать подстановочные знаки, например,

Sring query = "INSERT INTO users (id, user_name, password) VALUES(?,?,?)";
PreparedStatement statement = connection.preparedStatement(query);
for(User user: userList){
    statement.setString(1, user.getId()); //1 is the first ? (1 based counting)
    statement.setString(2, user.getUserName());
    statement.setString(3, user.getPassword()); 
    statement.addBatch();
}

Это создаст 1 PreparedStatement с запросом, показанным выше. Вы можете циклически проходить по списку, когда хотитевставить или каковы ваши намерения.Когда вы хотите казнить вас,

statement.executeBatch();
statement.clearBatch(); //If you want to add more, 
//(so you don't do the same thing twice)
5 голосов
/ 17 мая 2012

Я добавляю здесь дополнительный ответ специально для MySQL.

Я обнаружил, что время для выполнения пакета вставок было похоже на время, необходимое для выполнения отдельных вставок, даже с одной транзакцией вокругпакет.

Я добавил параметр rewriteBatchedStatements=true в свой URL-адрес jdbc и увидел значительное улучшение - в моем случае пакет из 200 вставок шел со 125 мсек.без параметра примерно от 10 до 15 мсек.с параметром.

См. MySQL и JDBC с rewriteBatchedStatements = true

...