Вопрос проверяет понимание работы JDBC, безопасности запросов и причин возникновения SQL-инъекций.
Statement формирует SQL-запрос как строку, а PreparedStatement использует параметры. В PreparedStatement SQL и данные передаются отдельно. Это предотвращает интерпретацию пользовательского ввода как части SQL-кода. Кроме безопасности, PreparedStatement может быть быстрее за счёт повторного использования плана запроса. Поэтому его используют по умолчанию.
Работа с БД через JDBC требует внимательного отношения к безопасности.
Statement — интерфейс JDBC для выполнения SQL-запросов, сформированных как строка.PreparedStatement — интерфейс JDBC для выполнения параметризованных SQL-запросов.
StatementЗапрос формируется целиком как строка.
Пример:
String sql = "SELECT * FROM users WHERE name = '" + name + "'";
Statement stmt = connection.createStatement();
stmt.executeQuery(sql);
Проблемы:
Уязвимость к SQL-инъекциям
Трудно экранировать данные
План запроса не переиспользуется
PreparedStatementSQL и параметры разделены.
Пример:
String sql = "SELECT * FROM users WHERE name = ?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, name);
ps.executeQuery();
Преимущества:
Защита от SQL-инъекций
Корректная обработка типов
Возможность переиспользования плана запроса
PreparedStatement защищает от инъекцийВажно понимать, что БД:
Сначала парсит SQL
Затем подставляет параметры как данные
Не исполняет параметры как код
Даже если параметр содержит SQL:
' OR 1=1 --
он будет трактоваться как обычная строка.
PreparedStatement — стандартный и безопасный способ работы с JDBC. Statement стоит использовать только в редких случаях с полностью контролируемым SQL.