Повторное использование PreparedStatement между методами?

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

А как быть с PreparedStatement повторное использование между различными вызовами метода? Повторное использование - "правило" все еще считается?

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

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

4 ответов


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

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

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

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

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


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

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

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


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

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

Если вы не используете пул соединений, то вы Золотой!


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