Должен ли я использовать PreparedStatements для всех моих вставок базы данных в Java? - PullRequest
5 голосов
/ 29 декабря 2008

Каков рекомендуемый способ экранирования переменных перед их вставкой в ​​базу данных на Java?

Как я понимаю, я могу использовать PreparedStatement.setString () для экранирования данных, но PreparedStatement кажется несколько нецелесообразным, если я не планирую повторять один и тот же запрос снова. Есть ли лучший способ сделать это без подготовки каждый запрос?

Ответы [ 5 ]

27 голосов
/ 29 декабря 2008

Да, используйте готовые заявления для всего.

  1. Они анализируются один раз.

  2. Они защищены от атак SQL-инъекций.

  3. Это лучший дизайн, потому что вы должны подумать о вашем SQL и как он используется.

Если вы думаете, что они используются только один раз, вы не смотрите на общую картину. Когда-нибудь ваши данные или ваша заявка изменится.


Edit.

Почему подготовленные операторы заставляют вас думать о вашем SQL?

  • Когда вы собираете строку (или просто выполняете буквальный блок текста), вы не создаете новый объект PreparedStatement. Вы просто выполняете SQL - это может быть сделано очень случайно.

  • Когда вам нужно создать (и сохранить) PreparedStatement, вам нужно еще немного подумать об инкапсуляции, распределении ответственности. Подготовка оператора является событием с состоянием перед любой обработкой SQL.

Дополнительная работа небольшая, но не незначительная. Это то, что заставляет людей задуматься об ORM и слое кэширования данных, и тому подобное, чтобы оптимизировать доступ к своей базе данных.

С Подготовленными утверждениями доступ к базе данных менее случайный, более преднамеренный.

9 голосов
/ 29 декабря 2008

Вы никогда не должны создавать SQL-запрос самостоятельно, используя конкатенацию строк. Вы никогда не должны вручную экранировать переменные / пользовательские данные при построении SQL-запроса. Фактическое экранирование, которое требуется, зависит от вашей базовой базы данных, и в какой-то момент кто-то забудет сбежать.

Суть в следующем: с подготовленными операторами невозможно создать оператор SQL для инъекций. С пользовательским экранированием это возможно. Выбор очевиден.

4 голосов
/ 29 декабря 2008

Подготовка заявления не так уж и дорога. Это безопаснее, чем большинство альтернатив.

3 голосов
/ 29 декабря 2008

Более того, не используйте JDBC API напрямую, потому что он подвержен ошибкам (например, не удается правильно очистить все ресурсы во всех случаях). Используйте вспомогательный объект JDBC, такой как интерфейс Spring JdbcOperations, который значительно уменьшает размер и ошибки вашего кода. Если вы используете Spring только для этой функции, вы по-прежнему пользуетесь огромным преимуществом по сравнению с прямым использованием JDBC API.

3 голосов
/ 29 декабря 2008

Я слышал аргумент, что PreparedStatement стоит немного больше накладных расходов по сравнению с простым оператором, и что это должно быть безопасно, если я не объединяю вводимые пользователем данные в свой запрос. Это может быть правдой, но дополнительные затраты не так велики, и запросы SQL меняются со временем. Если вы начинаете использовать заявление сегодня, потому что вы доказали себе, что ваш запрос защищен от инъекций, вы настраиваете себя на неудачу в тот день, когда программист по техническому обслуживанию изменяет SQL, чтобы принять пользовательский ввод, но не Подумайте, чтобы изменить это заявление на PreparedStatement. Мой совет - всегда использовать PreparedStatement, чтобы избежать неприятностей, прежде чем он найдет вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...