Ответ
Statement и PreparedStatement — это интерфейсы JDBC для выполнения SQL-запросов, но с ключевыми различиями в безопасности и производительности.
Statement
- Выполняет статические SQL-запросы, переданные в виде строки.
- Уязвим к SQL-инъекциям, так как параметры конкатенируются напрямую в строку запроса.
- Менее эффективен при многократном выполнении одного и того же запроса с разными параметрами, так как каждый раз запрос компилируется заново.
PreparedStatement
- Использует параметризованные запросы с плейсхолдерами (
?). - Защищает от SQL-инъекций, так как параметры передаются отдельно и экранируются драйвером БД.
- Повышает производительность при повторных вызовах: запрос компилируется один раз, а план выполнения может кэшироваться СУБД.
Пример использования:
// Statement (небезопасно и неэффективно)
String userInput = "123 OR 1=1";
Statement stmt = connection.createStatement();
String sql = "DELETE FROM users WHERE id = " + userInput; // Опасная конкатенация!
stmt.executeUpdate(sql); // Может удалить всех пользователей
// PreparedStatement (безопасно и эффективно)
int userId = 123;
String sql = "DELETE FROM users WHERE id = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, userId); // Параметр безопасно подставляется
pstmt.executeUpdate();
В тестировании важно проверять, что в коде приложения для всех операций с пользовательским вводом используется PreparedStatement, чтобы предотвратить уязвимости.