Подготовленный оператор является несколько более мощной версией оператора и всегда должен быть по меньшей мере таким же быстрым и простым в обращении, как и оператор.
Подготовленное заявление может быть параметризовано
Большинство реляционных баз данных обрабатывают запрос JDBC / SQL в четыре этапа:
- Разбор входящего SQL-запроса
- Скомпилируйте запрос SQL
- Планирование / оптимизация пути сбора данных
- Выполнить оптимизированный запрос / получить и вернуть данные
Оператор всегда будет проходить через четыре шага выше для каждого запроса SQL, отправляемого в базу данных. Подготовленный оператор предварительно выполняет шаги (1) - (3) в вышеописанном процессе выполнения. Таким образом, при создании подготовленного оператора некоторая предварительная оптимизация выполняется немедленно. В результате уменьшается нагрузка на ядро базы данных во время выполнения.
Теперь мой вопрос таков: «Есть ли какое-либо другое преимущество использования подготовленного заявления?»
Ответы:
Преимущества
PreparedStatement
:Предварительная компиляция и кэширование на стороне БД оператора SQL приводит к общему ускорению выполнения и возможности повторного использования одного и того же оператора SQL в пакетах .
Автоматическое предотвращение инъекций SQL атак на встроенном экранирование кавычек и других специальных символов. Обратите внимание, что для этого необходимо использовать любой из
PreparedStatement
setXxx()
методов для установки значений.и, следовательно , не вставляйте значения в строку SQL путем конкатенации строк.
Облегчает настройка нестандартных объектов Java в строке SQL, например
Date
,Time
,Timestamp
,BigDecimal
,InputStream
(Blob
) иReader
(Clob
). На большинстве этих типов вы не можете «просто» делать то,toString()
что вы делаете в простомStatement
. Вы могли бы даже реорганизовать все это для использованияPreparedStatement#setObject()
внутри цикла, как показано в методе утилиты ниже:Который может быть использован, как показано ниже:
источник
Statement
, но это может стоить проверить.Они предварительно скомпилированы (один раз), поэтому быстрее для повторного выполнения динамического SQL (где параметры меняются)
Кэширование операторов базы данных повышает производительность выполнения БД
В базах данных хранятся кэши планов выполнения ранее выполненных операторов. Это позволяет ядру базы данных повторно использовать планы для операторов, которые были выполнены ранее. Поскольку PreparedStatement использует параметры, каждый раз, когда он выполняется, он выглядит как один и тот же SQL, база данных может повторно использовать предыдущий план доступа, уменьшая обработку. Операторы «встраивают» параметры в строку SQL и поэтому не отображаются в БД в качестве одного и того же SQL, предотвращая использование кэша.
Протокол двоичной связи означает меньшую пропускную способность и более быстрые вызовы на сервер БД
Подготовленные операторы обычно выполняются по бинарному протоколу, отличному от SQL. Это означает, что в пакетах меньше данных, поэтому связь с сервером происходит быстрее. Как правило, сетевые операции на порядок медленнее, чем операции на диске, которые на порядок медленнее, чем операции ЦП в оперативной памяти. Следовательно, любое уменьшение количества данных, передаваемых по сети, будет иметь хорошее влияние на общую производительность.
Они защищают от внедрения SQL путем экранирования текста для всех предоставленных значений параметров.
Они обеспечивают более четкое разделение между кодом запроса и значениями параметров (по сравнению со связанными строками SQL), повышая удобочитаемость и помогая сопровождающим кода быстро понимать входные и выходные данные запроса.
В Java можно вызвать getMetadata () и getParameterMetadata (), чтобы отразить поля набора результатов и поля параметров, соответственно
В Java интеллектуально принимает объекты Java в качестве типов параметров через setObject, setBoolean, setByte, setDate, setDouble, setDouble, setFloat, setInt, setLong, setShort, setTime, setTimestamp - он преобразуется в формат типа JDBC, который можно понять с помощью DB (не только для toString) () формат).
В Java принимает SQL ARRAYs, в качестве типа параметра через метод setArray
В Java принимает CLOB, BLOB, OutputStreams и Readers в качестве параметров «подачи» через методы setClob / setNClob, setBlob, setBinaryStream, setCharacterStream / setAsciiStream / setNCharacterStream соответственно
В java позволяет устанавливать специфичные для БД значения для SQL DATALINK, SQL ROWID, SQL XML и NULL с помощью методов setURL, setRowId, setSQLXML и setNull
В Java наследует все методы из Statement. Он наследует метод addBatch и дополнительно позволяет добавлять набор значений параметров, чтобы соответствовать набору пакетных команд SQL через метод addBatch.
В Java специальный тип PreparedStatement (подкласс CallableStatement) позволяет выполнять хранимые процедуры - поддерживая высокую производительность, инкапсуляцию, процедурное программирование и SQL, администрирование / обслуживание / настройку БД логики, а также использование собственной логики и функций БД.
источник
Connection.createStatement
иConnection.prepareStatement
. Этот дизайн заставляет вас работать с интерфейсами, поэтому вам не нужно знать конкретные классы реализации и избегать ненужной тесной связи с такими классами реализации. Все объяснено с примерами в документации Java jdbc и документации Java. :)PreparedStatement
это очень хорошая защита (но не надежная защита) для предотвращения атак SQL-инъекций . Связывание значений параметров является хорошим способом защиты от «маленьких таблиц Бобби», которые могут сделать нежелательный визит.источник
ORDER BY
) и / или числовые константы , в некоторых местах (думаетLIMIT
,OFFSET
и другие постраничных решений), так что они могут быть атакованы SQL инъекцией, даже если Подготовленные заявления и параметризация используются везде , где возможно.Некоторые из преимуществ PreparedStatement по сравнению с Statement:
Узнайте больше о проблеме внедрения SQL на http://www.journaldev.com/2489/jdbc-statement-vs-preparedstatement-sql-injection-example
источник
нечего добавить,
1 - если вы хотите выполнить запрос в цикле (более 1 раза), подготовленный оператор может быть быстрее из-за упомянутой вами оптимизации.
2 - параметризованный запрос - хороший способ избежать SQL-инъекций. Параметризованные запросы доступны только в PreparedStatement.
источник
Постановка статична, а подготовленный отчет динамичен.
Постановка подходит для DDL и подготовлена отчетность для DML.
Оператор медленнее, а подготовленный оператор - быстрее.
больше различий (в архиве)
источник
Не могу сделать CLOB в заявлении.
И: (OraclePreparedStatement) ps
источник
По словам Mattjames
источник
подготовленный оператор игнорирует SQL-инъекцию
источник
источник
Оператор будет использоваться для выполнения статических операторов SQL, и он не может принимать входные параметры.
PreparedStatement будет использоваться для многократного динамического выполнения операторов SQL. Он примет входные параметры.
источник
Еще одна характеристика подготовленного или параметризованного запроса: ссылка взята из этой статьи.
Этот оператор является одной из особенностей системы базы данных, в которой один и тот же оператор SQL выполняется многократно с высокой эффективностью. Подготовленные заявления являются одним из видов шаблона и используются приложением с различными параметрами.
Шаблон выписки подготавливается и отправляется в систему базы данных, а система баз данных выполняет синтаксический анализ, компиляцию и оптимизацию этого шаблона и сохраняет его без выполнения.
Некоторые из параметров, например, где предложение не передается во время создания шаблона в более позднем приложении, отправляют эти параметры в систему базы данных, а система базы данных использует шаблон оператора SQL и выполняется в соответствии с запросом.
Подготовленные операторы очень полезны для SQL-инъекций, потому что приложение может подготовить параметр, используя различные методы и протоколы.
Когда количество данных увеличивается, а индексы часто меняются в это время, подготовленные операторы могут потерпеть неудачу, поскольку в этой ситуации требуется новый план запросов.
источник
Statement
интерфейс выполняет статические операторы SQL без параметровPreparedStatement
Интерфейс (расширяющий оператор) выполняет предварительно скомпилированный оператор SQL с / без параметровЭффективен для повторных казней
Это предварительно скомпилировано, так что это быстрее
источник
Не путайся: просто помни
источник
Я следовал всем ответам на этот вопрос, чтобы изменить работающий унаследованный код, используя -
Statement
(но с SQL-инъекциями) решение, использующееPreparedStatement
гораздо более медленный код из-за плохого понимания семантики вокругStatement.addBatch(String sql)
&PreparedStatement.addBatch()
.Поэтому я перечисляю свой сценарий здесь, чтобы другие не делали ту же ошибку.
Мой сценарий был
Итак, в приведенном выше коде у меня были тысячи различных запросов, все они были добавлены к одному и тому же оператору, и этот код работал быстрее, потому что операторы, которые не были кэшированы, были хорошими, и этот код редко выполнялся в приложении.
Теперь, чтобы исправить SQL-инъекции, я изменил этот код на
Итак, вы видите, я начал создавать тысячи
PreparedStatement
объектов и затем в конечном итоге не смог использовать пакетирование, потому что мой сценарий требовал, чтобы - были тысячи запросов UPDATE или INSERT, и все эти запросы оказались разными.Исправление внедрения SQL было обязательным без каких-либо затрат на снижение производительности, и я не думаю, что это возможно
PreparedStatement
в этом сценарии.Кроме того, когда вы используете встроенную функцию пакетирования, вам нужно беспокоиться о закрытии только одного оператора, но при этом подходе List необходимо закрыть оператор перед повторным использованием, повторное использование PreparedStatement
источник