#java #jdbc
#java #jdbc
Вопрос:
Я работал над сервлетом, который будет генерировать уникальный код и обновлять его в базе данных MySQL. Теперь, в этом случае, я хочу перехватить любое исключение, выданное в случае, если этот уникальный код уже существует в таблице MySQL, сгенерировать новый код и попытаться обновить базу данных. Проблема в том, что я хочу сделать это В самом цикле for. Код выглядит следующим образом:
try
{
connection = datasource.getConnection();
SQLUpdate = "INSERT INTO Voucher_dump VALUES( '" unique_code "','08-10-2011 04:48:48','0')";
PreparedStatement ps1 = connection.prepareStatement(SQLUpdate);
ps1.executeUpdate();
ResultSet r = ps1.getResultSet(); // this is where I'm checking if it's a duplicate
if(r==null)
out.println("This is a duplicate");
else out.println("Updated");
trial12= "08-10-2011 04:48:480.03999855056924717a";
SQLUpdate = "INSERT INTO Voucher_dump VALUES( '" trial12 "','08-10-2011 04:48:48','0')";
ps1 = connection.prepareStatement(SQLUpdate);
ps1.executeUpdate();
r = ps1.getResultSet();
if(r==null)
out.println("This is a duplicate");
else out.println("Updated");
}
catch (SQLException sqle)
{
sqle.printStackTrace();
}
Я не хочу ждать до конца всего цикла, чтобы перехватить исключение SQLException (я уже определил этот ключ в MySQL как основной). В тот момент, когда результат возвращается в виде повторяющейся записи, я хочу повторно сгенерировать этот ключ и повторить попытку обновления.Мой вывод для этого конкретного кода остается пустым на моей странице вывода (все остальные параметры отображаются правильно). Ни «Это дубликат» не отображается, ни «Обновляется». Возможно, ResultSet — не лучший способ сделать это. Не могли бы вы, ребята, дать мне несколько советов о том, что было бы наилучшим способом продвижения вперед?
Ответ №1:
Несколько советов в произвольном порядке:
- Закройте соединение в блоке finally.
- Закрывайте операторы по отдельности, если вы будете создавать многие из них перед закрытием соединения. («Много» определяется вашими администраторами баз данных.)
- Отформатируйте свой код.
- Не используйте стандартный вывод и / или стандартный вывод из реального кода. Выберите структуру ведения журнала.
- Рассмотрите возможность использования некоторых вспомогательных классов для упрощения (и исправления) доступа к базе данных, например JdbcTemplate от Spring.
- Обязательно включайте соответствующий контекст при публикации примера кода.
Из-за # 6 я не знаю, что out
это такое, но я подозреваю, что причина, по которой вы ничего не видите, заключается в том, что вы вставляете повторяющееся значение с первым оператором, что вызовет исключение SQLException из этой строки, а не в getResultSet()
, где вы, кажется, ожидаете этого. Поскольку ошибка записывается в стандартный вывод, она где-то появится в журналах вашего сервера, но ничего не будет записано out
. Я не уверен, почему вы думаете getResultSet()
, что вернет null или not null в зависимости от того, было ли нарушение ограничений. Взгляните на javadoc для этого метода.
Обновление: 7. Как указывает БалусК, никогда, никогда не объединяйте строку непосредственно в JDBC Statment. Используйте заполнители и set*
методы PreparedStatment. Для получения информации о внедрении SQL см. Википедию и XKCD.
Комментарии:
1. Потенциальная дыра в SQL-инъекции также может быть добавлена в список.
2. @BalusC: Ой. Хороший улов. Прошлой ночью я не спал слишком поздно.
Ответ №2:
Как насчет этого кода?
try {
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url dbName);
System.out.println("Connected to the database");
int i = 1; //get the unique code
boolean isInserted = false;
while (!isInserted) {
try {
PreparedStatement preparedStatement = conn.prepareStatement("INSERT INTO test values (?)");
preparedStatement.setInt(1, i);
preparedStatement.executeUpdate();
isInserted = true;
} catch (com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException e) { //Catch the particular exception which throws error on unique constraint. This may depend on Java/MySQL your version
i ; //get the next unique code
}
}
System.out.println("Disconnected from database");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (Exception e) {
}
}
Комментарии:
1. Кажется, это решает проблему с постером, но, пожалуйста, не ловите
Exception
. Это может непреднамеренно перехватывать и отключать исключения, отличные от тех, которые вы хотите обработать. Вместо этого перехватите наиболее конкретный подкласс Exception.2. Привет .. спасибо за всю вашу помощь…. попробую и дам вам знать.. Райан, я только что вставил ту часть кода, в которой я столкнулся с проблемами (1) и (2), которые уже были выполнены…. возьмет и другие …. большое спасибо!
3. Вы правы @S.L.Barth. Позаботится об этом в будущем. Спасибо за ваш ценный отзыв.