В чем разница между Statement и PreparedStatement в JDBC?

«В чем разница между Statement и PreparedStatement в JDBC?» — вопрос из категории Java, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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, чтобы предотвратить уязвимости.