Использование JDBC readyStatement в пакете
Я использую пакеты Statement
для запроса моей базы данных.
Iv'e сделал некоторые исследования сейчас, и я хочу переписать мое приложение, чтобы использовать 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
?
Ответы
Ответ 1
Прочтите раздел 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
}
Ответ 2
С 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)
Ответ 3
Я добавляю дополнительный ответ здесь специально для MySQL.
Я обнаружил, что время, затрачиваемое на сборку вставок, было похоже на время, затрачиваемое на отдельные вставки, даже с одной транзакцией вокруг пакета.
Я добавил параметр rewriteBatchedStatements=true
к моему URL-адресу jdbc и увидел резкое улучшение - в моем случае партия из 200 вставок прошла от 125 мс. без параметра примерно от 10 до 15 мс. с параметром.
См. MySQL и JDBC с rewriteBatchedStatements = true
Ответ 4
Пакетная вставка без PreparedStatement с использованием JDBC
int a= 100;
try {
for (int i = 0; i < 10; i++) {
String insert = "insert into usermaster"
+ "("
+ "userid"
+ ")"
+ "values("
+ "'" + a + "'"
+ ");";
statement.addBatch(insert);
System.out.println(insert);
a++;
}
dbConnection.commit();
} catch (SQLException e) {
System.out.println(" Insert Failed");
System.out.println(e.getMessage());
} finally {
if (statement != null) {
statement.close();
}
if (dbConnection != null) {
dbConnection.close();
}
}