Повторное использование PreparedStatement между методами? - PullRequest
6 голосов
/ 10 января 2011

Мы все знаем , что нам лучше использовать JDBC PreparedStatement, чем создавать новый экземпляр в цикле.

Но как справиться с PreparedStatement повторное использование между различными вызовами методов?Учитывается ли повторное использование «правила»?

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

Я знаю, что идеальным ответом может быть «это зависит».
НоЯ ищу лучшую практику для менее опытных разработчиков, чтобы они в большинстве случаев делали правильный выбор.

Ответы [ 4 ]

13 голосов
/ 10 января 2011

Конечно, экземпляр такого класса будет связан с подключением, что может быть недостатком

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

Объединение операторов - это работа драйвера JDBC, и большинство, если не все, из текущего поколения драйверов делают это для вас.Когда вы вызываете prepareStatement или prepareCall, драйвер будет обрабатывать повторное использование существующих ресурсов и предварительно скомпилированных операторов.

Statement объекты привязаны к соединению, и соединения должны использоваться и возвращатьсяв пул как можно быстрее.

Короче говоря, стандартная практика получения PreparedStatement в начале метода, многократно используя его в цикле, затем закрывая его в конце метода, является лучшей практикой.

6 голосов
/ 10 января 2011

Многие рабочие нагрузки баз данных связаны с ЦП, а не с IO. Это означает, что база данных тратит больше времени на выполнение работы, такой как анализ SQL-запросов и выяснение того, как их обрабатывать (выполнение «плана выполнения»), чем тратит доступ к диску. Это в большей степени относится к «транзакционным» рабочим нагрузкам, чем к «отчетным» рабочим нагрузкам, но в обоих случаях время, потраченное на подготовку плана, может оказаться больше, чем вы ожидаете.

Таким образом, это всегда хорошая идея, если оператор будет выполняться часто, и хлопоты по созданию (правильных) механизмов для кэширования PreparedStatements «между вызовами методов» стоят вашего времени разработчика. Как и в случае с производительностью, измерение является ключевым фактором, но если вы можете сделать это достаточно дешево, кэшируйте свое PreparedStatement по привычке.

Некоторые драйверы JDBC и / или пулы соединений предлагают прозрачное «подготовленное кэширование операторов», поэтому вам не придется делать это самостоятельно. До тех пор, пока вы понимаете поведение выбранной вами стратегии прозрачного кэширования, можно позволить ей отслеживать вещи ... чего вы действительно хотите избежать, так это попадания в базу данных.

0 голосов
/ 10 января 2011

Я не вижу разницы: если я выполняю один и тот же оператор несколько раз для одного и того же соединения, почему бы не использовать PreparedStatement каким-либо образом? Если несколько методов выполняют один и тот же оператор, то, возможно, этот оператор должен быть инкапсулирован в своем собственном методе (или даже в своем собственном классе). Таким образом, вам не нужно будет пропускать PreparedStatement.

0 голосов
/ 10 января 2011

Да, его можно использовать повторно, но я считаю, что это учитывается только в том случае, если используется один и тот же объект Connection и если вы используете пул соединений с базой данных (например, из веб-приложения), тогда объекты Connectionбудет потенциально отличаться каждый раз.

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

Если вы не используете пул подключений, значит, у вас есть золотой!

...