Разница между выпиской и подготовленным состоянием - PullRequest
202 голосов
/ 17 июля 2010

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

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

  1. Разбор входящего SQL-запроса
  2. Скомпилируйте запрос SQL
  3. Планирование / оптимизация пути сбора данных
  4. Выполнить оптимизированный запрос / получить и вернуть данные

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

Теперь мой вопрос таков: «Есть ли какое-либо другое преимущество использования Подготовленного заявления?»

Ответы [ 15 ]

4 голосов
/ 30 апреля 2013

Оператор будет использоваться для выполнения статических операторов SQL и не может принимать входные параметры.

PreparedStatement будет использоваться для многократного динамического выполнения операторов SQL. Он примет входные параметры.

4 голосов
/ 13 сентября 2010
  • Легче читать
  • Вы можете легко сделать строку запроса постоянной
3 голосов
/ 05 ноября 2012

Statement интерфейс выполняет статические операторы SQL без параметров

PreparedStatement интерфейс (расширяющий оператор) выполняет предварительно скомпилированный оператор SQL с / без параметров

  1. Эффективно дляповторное выполнение

  2. Он предварительно скомпилирован, поэтому он быстрее

1 голос
/ 21 марта 2015

Не запутайтесь: просто запомните

  1. Оператор используется для статических запросов, таких как DDL, т.е. create, drop, alter и prepareStatement используется для динамических запросов, то есть DML-запроса.
  2. В операторе запрос не прекомпилируется, а в режиме prepareStatement запрос предварительно компилируется, поскольку этот метод prepareStatement является эффективным по времени.
  3. prepareStatement принимает аргумент во время создания, в то время как Statement не принимает аргументы. Например, если вы хотите создать таблицу и вставить элемент тогда :: Создайте таблицу (статическую), используя элемент Statement и Insert (динамический), используя prepareStatement.
0 голосов
/ 29 июня 2019

Я следовал всем ответам на этот вопрос, чтобы изменить работающий унаследованный код, используя - Statement (но с SQL-инъекциями) на решение, использующее PreparedStatement с гораздо более медленным кодом из-за плохого понимания семантики около Statement.addBatch(String sql) & PreparedStatement.addBatch().

Итак, я перечисляю свой сценарий здесь, чтобы другие не совершали ту же ошибку.

Мой сценарий был

    Statement statement = connection.createStatement();

        for (Object object : objectList) {
         //Create a query which would be different for each object 
         // Add this query to statement for batch using - statement.addBatch(query);
        }
   statement.executeBatch();

Итак, в приведенном выше коде у меня были тысячи различных запросов, все они были добавлены к одному и тому же оператору, и этот код работал быстрее, потому что операторы, которые не были кэшированы, были хорошими, и этот код редко выполнялся в приложении.

Теперь, чтобы исправить SQL-инъекции, я изменил этот код на

    List<PreparedStatement> pStatements = new ArrayList<>();    
                        for (Object object : objectList) {
                         //Create a query which would be different for each object 
                         PreparedStatement pStatement =connection.prepareStatement(query);
                         // This query can't be added to batch because its a different query so I used list. 
                   //Set parameter to pStatement using object 
                         pStatements.add(pStatement);
                        }// Object loop
    // In place of statement.executeBatch(); , I had to loop around the list & execute each update separately          
    for (PreparedStatement ps : pStatements) {
                ps.executeUpdate();
            }

Итак, вы видите, я начал создавать тысячи PreparedStatement объектов и затем в конечном итоге не смог использовать пакетную обработку, потому что мой сценарий требовал, чтобы - были тысячи запросов UPDATE или INSERT, и все эти запросы оказались разными .

Исправление внедрения SQL было обязательным без каких-либо затрат на снижение производительности, и я не думаю, что это возможно с PreparedStatement в этом сценарии.

Кроме того, когда вы используете встроенную функцию пакетирования, вам нужно беспокоиться о закрытии только одного оператора, но при этом подходе List необходимо закрыть оператор перед повторным использованием, Повторное использование PreparedStatement

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