Вы должны редко использовать Statement
; Вы почти всегда хотите PreparedStatement
. Использование Statement
означает, что вы не можете вводить какой-либо пользовательский ввод в оператор. Если вы попытаетесь, например: statement.executeQuery("SELECT * FROM users WHERE username = '" + userInput + "'");
, вы только что написали утечку в системе безопасности. Что, если пользователь отправит в качестве ввода: "foo'; DROP TABLE users; EXECUTE SHELL 'rm -rf /'; --"?
- единственный выход - это избежать его, а PreparedStatement
- как это сделать.
соединения - это ресурсы; они должны быть закрыты. То же самое можно сказать и о заявлениях (даже подготовленных), а также о наборах результатов. Каждый из них должен рассматриваться как ресурс.
Для работы с ресурсами вы пишете такой код:
try (Connection con = DriverManager.getConnection(...)) {
try (PreparedStatement ps = con.prepareStatement("SELECT * FROM users WHERE username = ?")) {
ps.setString(1, username);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
// handle a row worth of results here
}
}
}
}
Эта конструкция гарантирует, что независимо от того, что происходит ( вы возвращаетесь, выбрасываете, выбрасываете исключение - не имеет значения), когда код выходит за скобки, ресурс удаляется должным образом. Невыполнение этого требования означает, что механизм базы данных со временем становится более запаздывающим, и в конечном итоге ваше приложение падает, поскольку база данных перестает давать вам больше подключений, позволяющих сидеть без дела.