Java JDBC PreparedStatement — это особый вид объекта Java JDBC Statement с некоторыми полезными дополнительными функциями. Помните, что вам нужен оператор для выполнения запроса или обновления. Вы можете использовать Java JDBC PreparedStatement вместо Statement и пользоваться преимуществами PreparedStatement.
Основные функции Java JDBC PreparedStatement:
- Легко вставить параметры в оператор SQL.
- Легко использовать PreparedStatement с новыми значениями параметров.
- Может повысить производительность выполненных заявлений.
- Позволяет упростить пакетные обновления.
Я покажу вам, как вставить параметры в операторы SQL, а также как использовать PreparedStatement. Пакетные обновления описаны в отдельно.
Вот быстрый пример, чтобы дать вам представление о том, как это выглядит в коде:
String sql = "update people set firstname=? , lastname=? where id=?";
PreparedStatement preparedStatement =
connection.prepareStatement(sql);
preparedStatement.setString(1, "Gary");
preparedStatement.setString(2, "Larson");
preparedStatement.setLong(3, 123);
int rowsAffected = preparedStatement.executeUpdate();
Создание PreparedStatement
Прежде чем вы сможете использовать PreparedStatement, вы должны сначала создать его. Вы делаете это с помощью Connection.prepareStatement(), например так:
String sql = "select * from people where id=?";
PreparedStatement preparedStatement =
connection.prepareStatement(sql);
PreparedStatement теперь готов к вставке параметров.
Вставка параметров в PreparedStatement
Везде, где вам нужно вставить параметр в ваш SQL, вы пишете знак вопроса(?). Например:
String sql = "select * from people where id=?";
Как только PreparedStatement создан(подготовлен) для вышеприведенного оператора SQL, вы можете вставить параметры в расположение знака вопроса. Это делается с помощью многих методов setXXX(). Вот пример:
preparedStatement.setLong(1, 123);
Первое число(1) — это индекс параметра, для которого нужно вставить значение. Второе число(123) — это значение для вставки в оператор SQL.
Вот тот же пример с более подробной информацией:
String sql = "select * from people where id=?";
PreparedStatement preparedStatement =
connection.prepareStatement(sql);
preparedStatement.setLong(123);
Вы можете иметь более одного параметра в операторе SQL. Просто вставьте более одного знака вопроса. Вот простой пример:
String sql = "select * from people where firstname=? and lastname=?";
PreparedStatement preparedStatement =
connection.prepareStatement(sql);
preparedStatement.setString(1, "John");
preparedStatement.setString(2, "Smith");
Выполнение PreparedStatement
Выполнение PreparedStatement выглядит как выполнение обычного оператора. Чтобы выполнить запрос, вызовите метод executeQuery() или executeUpdate. Вот пример executeQuery():
String sql = "select * from people where firstname=? and lastname=?";
PreparedStatement preparedStatement =
connection.prepareStatement(sql);
preparedStatement.setString(1, "John");
preparedStatement.setString(2, "Smith");
ResultSet result = preparedStatement.executeQuery();
Как видите, метод executeQuery() возвращает ResultSet. Итерация ResultSet описана в тексте запроса к базе данных.
Вот пример executeUpdate():
String sql = "update people set firstname=? , lastname=? where id=?";
PreparedStatement preparedStatement =
connection.prepareStatement(sql);
preparedStatement.setString(1, "Gary");
preparedStatement.setString(2, "Larson");
preparedStatement.setLong(3, 123);
int rowsAffected = preparedStatement.executeUpdate();
Метод executeUpdate() используется при обновлении базы данных. Он возвращает int, который сообщает, сколько записей в базе данных было затронуто обновлением.
Повторное использование PreparedStatement
Когда PreparedStatement подготовлен, его можно использовать повторно после выполнения. Вы повторно используете PreparedStatement, устанавливая новые значения для параметров, а затем выполняете его снова. Вот простой пример:
String sql = "update people set firstname=? , lastname=? where id=?";
PreparedStatement preparedStatement =
connection.prepareStatement(sql);
preparedStatement.setString(1, "Gary");
preparedStatement.setString(2, "Larson");
preparedStatement.setLong(3, 123);
int rowsAffected = preparedStatement.executeUpdate();
preparedStatement.setString(1, "Stan");
preparedStatement.setString(2, "Lee");
preparedStatement.setLong(3, 456);
int rowsAffected = preparedStatement.executeUpdate();
Это работает и для выполнения запросов, используя метод executeQuery(), который возвращает ResultSet.
Производительность PreparedStatement
Для базы данных требуется время, чтобы проанализировать строку SQL и создать план запроса для нее. План запроса — это анализ того, как база данных может выполнить запрос наиболее эффективным способом.
Если вы отправляете новый полный оператор SQL для каждого запроса или обновления в базу данных, база данных должна проанализировать SQL и для запросов создать план запроса. Повторно используя существующее PreparedStatement, вы можете повторно использовать синтаксический анализ SQL и план запроса для последующих запросов. Это ускоряет выполнение запросов, уменьшая накладные расходы при разборе и планировании запросов при каждом выполнении.
Существует два уровня потенциального повторного использования для PreparedStatement.
- Повторное использование PreparedStatement драйвером JDBC.
- Повторное использование PreparedStatement базой данных.
Прежде всего, драйвер JDBC может внутренне кэшировать объекты PreparedStatement и, таким образом, повторно использовать объекты PreparedStatement. Это может сэкономить немного времени создания PreparedStatement.
Во-вторых, кэшированный синтаксический анализ и план запросов могут быть повторно использованы в приложениях Java, например, на серверах приложений в кластере, используя одну и ту же базу данных.
Вот схема, иллюстрирующая кэширование операторов в базе данных:

На диаграмме не показан кэш PreparedStatement драйвера JDBC.
