Используя JDBC prepareStatement в пакете
Я использую Statement
S пакетов для запроса моей базы данных. Я провел некоторое исследование сейчас, и я хочу переписать свое приложение для использования preparedStatement
вместо этого, но у меня нет времени, чтобы выяснить, как добавить запросы к preparedStatement
партия.
Это то, что я делаю сейчас:
private void addToBatch(String sql) throws SQLException{
sttmnt.addBatch(sql);
batchSize++;
if (batchSize == elementsPerExecute){
executeBatches();
}
}
где sttmnt
является членом класса типа Statement
,
Что я хочу сделать, это использовать preparedStatement
"s setString(int, String)
метод, чтобы установить некоторые динамические данные, а затем добавить их в пакет.
К сожалению, я не совсем понимаю, как это работает, и как я могу использовать setString(int, String)
для конкретного sql в пакете или создать новый preparedStatemnt
для каждого sql у меня есть, а затем объединить их всех в одну партию.
это возможно сделать? или я действительно что-то упустил в моем понимании preparedStatement
?
3 ответа
Прочитайте раздел 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
}
С 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)
Я добавляю дополнительный ответ здесь специально для MySQL.
Я обнаружил, что время выполнения пакета вставок было похоже на время выполнения отдельных вставок, даже с одной транзакцией вокруг пакета.
Я добавил параметр rewriteBatchedStatements=true
на мой JDBC URL, и увидел значительное улучшение - в моем случае, партия из 200 вставок пошла от 125 мсек. без параметра примерно от 10 до 15 мсек. с параметром.
Пакетная вставка без 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();
}
}