Когда мы должны использовать PreparedStatement вместо Statement?

Я знаю преимущества использования PreparedStatement, которые

  • запрос перезаписывается и компилируется сервером базы данных
  • защита от SQL-инъекций

Но я хочу знать, когда мы используем его вместо Statement?

Ответ 1

  • Запрос перезаписывается и компилируется сервером базы данных

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

  • Защита от SQL-инъекций

    Это преимущество, которое вы почти всегда хотят, следовательно, повод для используйте PreparedStatement каждый раз. Это следствие того, что параметризовать запрос, но он сделать его намного безопаснее. только время я могу думать, что это не было бы полезно, если бы вы были разрешая запросы базы данных adhoc; Вы может просто использовать выражение объект, если вы прототипировали приложение и его быстрее для вас, или если запрос не содержит Параметры.

Ответ 2

Спросите у Tom мнение:

Использование Statement в JDBC должно быть на 100% локализовано для использования в DDL (ALTER, CREATE, GRANT и т.д.), Поскольку они являются единственными типами операторов, которые не могут принимать BIND ПЕРЕМЕННЫЕ.

PreparedStatements или CallableStatements следует использовать для КАЖДОГО ДРУГОГО типа утверждения (DML, Запросы). Поскольку это типы операторов, которые принимают переменные связывания.

Это факт, правило, законное использование готовых заявлений ВЕЗДЕ. Использовать ЗАЯВЛЕНИЯ почти нет.

Он специально говорит о Oracle, но тот же принцип применяется к любой базе данных, которая кэширует планы выполнения.

Приложения для баз данных, которые одновременно масштабируют и предотвращают атаки SQL-инъекций? Какая минута?

Ответ 3

Я бы включил этот раунд: в публично распространенном приложении вы обычно должны всегда использовать подготовленные операторы , если у вас нет действительно убедительной причины не для, и вы всегда должны параметры поставки "должным образом" в подготовленный оператор, а не путем объединения их в строку запроса.

Почему? Ну, в основном из-за причин, которые вы дали (или, по крайней мере, второго)...

Ответ 4

PreparedStatements следует использовать очень осторожно в предложениях WHERE.

Предположим, что таблица определена как:

create table t (int o, k varchar(100), v varchar(100))

(например, o: идентификатор объекта (внешний ключ), k: атрибут-ключ, v: атрибут-значение ").

Кроме того, существует индекс (не уникальный) на v.

create index ixt on t ( v )

Предположим, что эта таблица содержит 200 миллионов вставленных строк:

for (i = 0; i < 100*1000*1000; i++) {
  insert into t (o,k,v) values (i,'k1','v1');
  insert into t (o,k,v) values (i,'k2', Convert(i, varchar));
}

( "Таким образом, каждый объект o имеет атрибуты k1 = v1 и k2 = o" )

Тогда вы не должны создавать запросы, например:

select o,p,v from t as tx, t as ty where tx.o=ty.o and tx.k=? and tx.v=? and ty.k=? and ty.v=?

( "найти объекты, имеющие два заданных атрибута" )

Мой опыт работы с ORACLE и MSSQL заключается в том, что для выполнения этих запросов может потребоваться много минут. Это верно, даже если ни одна строка не соответствует предложению where. Это зависит от того, как SQL-Server решает сначала искать tx.v или ty.v.

Один shoud помещает значения для столбцов k и v directy в оператор. Я думаю, это связано с тем, что SQL-серверы учитывают значения при вычислении плана выполнения.

Запрос выглядит так, как всегда, после миллисекунд:

select o,p,v from t as tx, t as ty where tx.o=ty.o and tx.k='k1' and tx.v='v1' and ty.k='k2' and ty.v='1234'

( "SQL-Server всегда будет искать сначала для v = '1234', а затем для v = 'v1'" )

С уважением
Вольфганг

Ответ 5

Я предпочитаю использовать PreparedStatement, если я хочу выполнить запрос. (Вставить, Выбрать,... и т.д.). Тот же расозон, что и другим, написанным выше.

Но если мне нужно использовать динамические параметры, я просто использую Statement, потому что я могу легко построить свою строку SQL, которую просто выполнить. (inmyopinion) Если вы хотите построить динамический запрос с помощью readyStatment, у вас будет огромный код спагетти, который никто не понимает.

Ответ 6

Statement: каждый раз, когда выполняется запрос sql, этот SQL-запрос отправляется в СУБД, где он компилируется. Таким образом, он увеличивает нагрузку на сервер и снижает производительность.

connection con=null; 
  String sql="select * from employee where id=5";
Statement st=conn.createStatement();

PreparedStatement. В отличие от Statement PreparedStatement, в качестве параметра при создании создается запрос sql.

connection con=null; 
String sql="select * from employee where id=?";
PreparedStatement ps=conn.prepareStatement(sql);

Этот оператор sql отправляется в базу данных, где он скомпилирован. Таким образом, в prepareStatement скомпилировано происходит только один раз, но в скомпилированном выражении происходит каждый раз, когда вызывается Statement.

Ответ 7

Вы всегда можете использовать PreparedStatement вместо Statment (выбрать, вставить, обновить, удалить). Лучшая производительность и защита от внедрения SQL.

Но не используйте его с динамическим запросом, таким как запрос с WHERE variable IN [ hundreds possibilities ]:

  1. Это непродуктивно, вы теряете производительность и память, потому что вы кешируете каждый раз новый запрос, и PreparedStatement не только для SQL-инъекций, но и для производительности. В этом случае оператор не будет медленнее.

  2. В вашем пуле есть предел PreparedStatment (по умолчанию -1, но вы должны его ограничить), и вы достигнете этого предела! и если у вас нет предела или очень большой предел, у вас есть некоторый риск утечки памяти, а в крайнем случае ошибки OutofMemory. Так что, если это для вашего маленького личного проекта, используемого 3 пользователями, это не драматично, но вы не хотите этого, если вы в большой компании и что ваше приложение используют тысячи людей и миллион запросов.

Некоторое чтение. IBM: вопросы использования памяти при использовании подготовленного кэширования операторов

Ответ 8

Помимо предотвращения внедрения SQL, переносимость форматирования (которую вы не можете получить от Statement), производительность является очевидной причиной. Однако PreparedStatement не приносит никаких штрафных санкций. Например, он работает медленнее, чем Statement, если работает только один раз, так как есть некоторые накладные расходы. Поэтому общая идея PreparedStatement должна использоваться, когда вы выполняете один и тот же запрос много раз. Тем не менее, сколько накладных расходов является специфичным для сервера баз данных, поэтому точно, когда выбрать PreparedStatement over Statement, из соображений эффективности, действительно должно быть основано на вашем фактическом опыте/экспериментах конкретного сервера базы данных.