Вопрос-ответ

Difference between Statement and PreparedStatement

Разница между оператором и PreparedStatement

Подготовленный оператор - это немного более мощная версия оператора, и он всегда должен быть по крайней мере таким же быстрым и простым в обращении, как и оператор.
Подготовленный оператор может быть параметризован

Большинство реляционных баз данных обрабатывает запрос JDBC / SQL в четыре этапа:


  1. Анализ входящего SQL-запроса

  2. Скомпилируйте SQL-запрос

  3. Планирование / оптимизация пути сбора данных

  4. Выполнение оптимизированного запроса / получение и возврат данных

Оператор всегда выполняет четыре описанных выше шага для каждого SQL-запроса, отправляемого в базу данных. Подготовленный оператор предварительно выполняет шаги (1) - (3) в описанном выше процессе выполнения. Таким образом, при создании подготовленного оператора сразу выполняется некоторая предварительная оптимизация. Результатом является уменьшение нагрузки на ядро базы данных во время выполнения.

Теперь мой вопрос заключается в следующем:

"Есть ли какие-либо другие преимущества использования Prepared Statement?"

Переведено автоматически
Ответ 1

Преимущества PreparedStatement:


  • Предварительная компиляция и кэширование SQL-инструкции на стороне базы данных приводит к общему ускорению выполнения и возможности повторного использования одной и той же SQL-инструкции пакетами.


  • Автоматическое предотвращение атак SQL-инъекций за счет встроенного экранирования кавычек и других специальных символов. Обратите внимание, что для этого требуется использовать любой из PreparedStatement setXxx() методов для установки значений


    preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email, birthdate, photo) VALUES (?, ?, ?, ?)");
    preparedStatement.setString(1, person.getName());
    preparedStatement.setString(2, person.getEmail());
    preparedStatement.setTimestamp(3, new Timestamp(person.getBirthdate().getTime()));
    preparedStatement.setBinaryStream(4, person.getPhoto());
    preparedStatement.executeUpdate();

    и, следовательно, не вставляйте значения в строку SQL путем объединения строк.


    preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email) VALUES ('" + person.getName() + "', '" + person.getEmail() + "'");
    preparedStatement.executeUpdate();

  • Упрощает настройку нестандартных объектов Java в строке SQL, например, Date, Time, Timestamp, BigDecimal InputStream (Blob) и Reader (Clob). Для большинства из этих типов вы не можете "просто" выполнить toString() как вы бы сделали в простом Statement. Вы могли бы даже реорганизовать все это до использования PreparedStatement#setObject() внутри цикла, как показано в приведенном ниже методе утилиты:


    public static void setValues(PreparedStatement preparedStatement, Object... values) throws SQLException {
    for (int i = 0; i < values.length; i++) {
    preparedStatement.setObject(i + 1, values[i]);
    }
    }

    Который можно использовать, как показано ниже:


    preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email, birthdate, photo) VALUES (?, ?, ?, ?)");
    setValues(preparedStatement, person.getName(), person.getEmail(), new Timestamp(person.getBirthdate().getTime()), person.getPhoto());
    preparedStatement.executeUpdate();

Ответ 2

  1. Они предварительно компилируются (один раз), поэтому быстрее при повторном выполнении динамического SQL (при изменении параметров)


  2. Кэширование инструкций базы данных повышает производительность выполнения БД


    Базы данных хранят кэши планов выполнения для ранее выполненных инструкций. Это позволяет database Engine повторно использовать планы для инструкций, которые были выполнены ранее. Поскольку PreparedStatement использует параметры, каждый раз при его выполнении он отображается как один и тот же SQL, база данных может повторно использовать предыдущий план доступа, сокращая обработку. Операторы "встраивают" параметры в строку SQL и поэтому не отображаются в БД как один и тот же SQL, предотвращая использование кэша.


  3. Двоичный протокол связи означает меньшую пропускную способность и более быстрые вызовы связи на сервер БД


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


  4. Они защищают от SQL-инъекции, экранируя текст для всех предоставленных значений параметров.


  5. Они обеспечивают более четкое разделение между кодом запроса и значениями параметров (по сравнению с объединенными строками SQL), повышая читаемость и помогая разработчикам кода быстро понимать входные и выходные данные запроса.


  6. В Java можно вызывать getMetadata() и getParameterMetadata() для отображения полей результирующего набора и полей параметров соответственно


  7. В Java интеллектуальным образом принимает объекты java в качестве типов параметров через setObject, setBoolean, setByte, setDate, setDouble, setDouble, SetFloat, SetInt, setLong, setShort, setTime, setTimestamp - преобразует в формат типа JDBC, понятный для DB (не только в формат toString()).


  8. В Java принимает массивы SQL в качестве типа параметра с помощью метода setArray


  9. В Java принимает CLOBs, BLOBs, OutputStreams и Readers в качестве "каналов" параметров с помощью методов setClob / setNClob, setBlob, setBinaryStream, setCharacterStream / setAsciiStream / setNCharacterStream соответственно


  10. В Java позволяет устанавливать значения, зависящие от базы данных, для SQL DATALINK, SQL ROWID, SQL XML и NULL с помощью методов setUrl, setRowId, setSQLXML и SetNull


  11. В Java наследует все методы из Statement . Он наследует метод addBatch и дополнительно позволяет добавлять набор значений параметров для соответствия набору пакетных SQL-команд с помощью метода addBatch .


  12. В Java специальный тип PreparedStatement (подкласс CallableStatement) позволяет выполнять хранимые процедуры, поддерживая высокую производительность, инкапсуляцию, процедурное программирование и SQL, администрирование / обслуживание / настройку логики БД и использование проприетарной логики и функций БД


Ответ 3

PreparedStatement это очень хорошая защита (но не надежная) для предотвращения атак SQL-инъекций. Привязка значений параметров - хороший способ защиты от нежелательного посещения "маленьких таблиц Бобби".

Ответ 4

Некоторые преимущества PreparedStatement перед Statement заключаются в следующем:


  1. PreparedStatement помогает нам предотвращать атаки с использованием SQL-инъекций, поскольку он автоматически экранирует специальные символы.

  2. PreparedStatement позволяет нам выполнять динамические запросы с вводом параметров.

  3. PreparedStatement предоставляет различные типы методов setter для установки входных параметров для запроса.

  4. PreparedStatement работает быстрее, чем Statement . Это становится более заметным, когда мы повторно используем PreparedStatement или используем его методы пакетной обработки для выполнения нескольких запросов.

  5. PreparedStatement помогает нам в написании объектно-ориентированного кода с использованием методов setter, тогда как в случае с оператором мы должны использовать конкатенацию строк для создания запроса. Если требуется установить несколько параметров, написание запроса с использованием конкатенации строк выглядит очень некрасиво и чревато ошибками.

Подробнее о проблеме SQL-инъекции читайте на http://www.journaldev.com/2489/jdbc-statement-vs-preparedstatement-sql-injection-example

java jdbc