Учебники

JDBC — Заявления, PreparedStatement и CallableStatement

Как только соединение установлено, мы можем взаимодействовать с базой данных. Интерфейсы JDBC Statement, CallableStatement и PreparedStatement определяют методы и свойства, которые позволяют отправлять команды SQL или PL / SQL и получать данные из вашей базы данных.

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

В следующей таблице приведены сводные данные о назначении каждого интерфейса для выбора используемого интерфейса.

Интерфейсы Рекомендуемое использование
утверждение Используйте это для общего доступа к вашей базе данных. Полезно, когда вы используете статические операторы SQL во время выполнения. Интерфейс оператора не может принимать параметры.
Подготовленное заявление Используйте это, когда вы планируете использовать операторы SQL много раз. Интерфейс PreparedStatement принимает входные параметры во время выполнения.
CallableStatement Используйте это, когда вы хотите получить доступ к хранимым процедурам базы данных. Интерфейс CallableStatement также может принимать входные параметры времени выполнения.

Объекты Statement

Создание объекта выписки

Прежде чем вы сможете использовать объект Statement для выполнения оператора SQL, вам необходимо создать его с помощью метода createStatement () объекта Connection, как в следующем примере:

Statement stmt = null;
try {
   stmt = conn.createStatement( );
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

Создав объект Statement, вы можете использовать его для выполнения оператора SQL одним из трех его методов execute.

  • boolean execute (String SQL) : возвращает логическое значение true, если можно получить объект ResultSet; в противном случае возвращается false. Используйте этот метод для выполнения операторов SQL DDL или когда вам нужно использовать действительно динамический SQL.

  • int executeUpdate (String SQL) : возвращает количество строк, затронутых выполнением оператора SQL. Используйте этот метод для выполнения операторов SQL, для которых ожидается получение ряда затронутых строк — например, оператора INSERT, UPDATE или DELETE.

  • ResultSet executeQuery (String SQL) : возвращает объект ResultSet. Используйте этот метод, когда вы ожидаете получить набор результатов, как если бы вы использовали инструкцию SELECT.

boolean execute (String SQL) : возвращает логическое значение true, если можно получить объект ResultSet; в противном случае возвращается false. Используйте этот метод для выполнения операторов SQL DDL или когда вам нужно использовать действительно динамический SQL.

int executeUpdate (String SQL) : возвращает количество строк, затронутых выполнением оператора SQL. Используйте этот метод для выполнения операторов SQL, для которых ожидается получение ряда затронутых строк — например, оператора INSERT, UPDATE или DELETE.

ResultSet executeQuery (String SQL) : возвращает объект ResultSet. Используйте этот метод, когда вы ожидаете получить набор результатов, как если бы вы использовали инструкцию SELECT.

Закрытие объекта выписки

Подобно тому, как вы закрываете объект Connection для сохранения ресурсов базы данных, по той же причине вы также должны закрывать объект Statement.

Простой вызов метода close () сделает эту работу. Если вы сначала закроете объект Connection, он также закроет объект Statement. Тем не менее, вы всегда должны явно закрывать объект Statement, чтобы обеспечить правильную очистку.

Statement stmt = null;
try {
   stmt = conn.createStatement( );
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   stmt.close();
}

Для лучшего понимания мы предлагаем вам изучить учебное пособие « Заявление — пример» .

Объекты PreparedStatement

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

Это утверждение дает вам гибкость в предоставлении аргументов динамически.

Создание объекта PreparedStatement

PreparedStatement pstmt = null;
try {
   String SQL = "Update Employees SET age = ? WHERE id = ?";
   pstmt = conn.prepareStatement(SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

Все параметры в JDBC представлены символом ? символ, который известен как маркер параметра. Вы должны предоставить значения для каждого параметра перед выполнением оператора SQL.

Методы setXXX () связывают значения с параметрами, где XXX представляет тип данных Java значения, которое вы хотите связать с входным параметром. Если вы забудете указать значения, вы получите исключение SQLException.

Каждый маркер параметра обозначается своей порядковой позицией. Первый маркер представляет позицию 1, следующую позицию 2 и так далее. Этот метод отличается от метода индексов массива Java, который начинается с 0.

Все методы объекта Statement для взаимодействия с базой данных (a) execute (), (b) executeQuery () и (c) executeUpdate () также работают с объектом PreparedStatement. Однако методы модифицируются для использования операторов SQL, которые могут вводить параметры.

Закрытие объекта PreparedStatement

Подобно тому, как вы закрываете объект Statement, по той же причине вам также следует закрыть объект PreparedStatement.

Простой вызов метода close () сделает эту работу. Если вы сначала закроете объект Connection, он также закроет объект PreparedStatement. Однако вы всегда должны явно закрывать объект PreparedStatement, чтобы обеспечить правильную очистку.

PreparedStatement pstmt = null;
try {
   String SQL = "Update Employees SET age = ? WHERE id = ?";
   pstmt = conn.prepareStatement(SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   pstmt.close();
}

Для лучшего понимания давайте изучим Prepare — Пример кода .

Объекты CallableStatement

Подобно тому, как объект Connection создает объекты Statement и PreparedStatement, он также создает объект CallableStatement, который будет использоваться для выполнения вызова хранимой процедуры базы данных.

Создание объекта CallableStatement

Предположим, вам нужно выполнить следующую хранимую процедуру Oracle:

CREATE OR REPLACE PROCEDURE getEmpName 
   (EMP_ID IN NUMBER, EMP_FIRST OUT VARCHAR) AS
BEGIN
   SELECT first INTO EMP_FIRST
   FROM Employees
   WHERE ID = EMP_ID;
END;

ПРИМЕЧАНИЕ. Вышеописанная хранимая процедура была написана для Oracle, но мы работаем с базой данных MySQL, поэтому давайте создадим такую ​​же хранимую процедуру для MySQL, как описано ниже, для ее создания в базе данных EMP:

DELIMITER $$

DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$
CREATE PROCEDURE `EMP`.`getEmpName` 
   (IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255))
BEGIN
   SELECT first INTO EMP_FIRST
   FROM Employees
   WHERE ID = EMP_ID;
END $$

DELIMITER ;

Существуют три типа параметров: IN, OUT и INOUT. Объект PreparedStatement использует только параметр IN. Объект CallableStatement может использовать все три.

Вот определения каждого —

параметр Описание
В Параметр, значение которого неизвестно при создании оператора SQL. Вы связываете значения с параметрами IN с помощью методов setXXX ().
ИЗ Параметр, значение которого предоставляется оператором SQL, который он возвращает. Вы извлекаете значения из параметров OUT с помощью методов getXXX ().
INOUT Параметр, который предоставляет как входные, так и выходные значения. Вы связываете переменные с помощью методов setXXX () и извлекаете значения с помощью методов getXXX ().

В следующем фрагменте кода показано, как использовать метод Connection.prepareCall () для создания экземпляра объекта CallableStatement на основе предыдущей хранимой процедуры.

CallableStatement cstmt = null;
try {
   String SQL = "{call getEmpName (?, ?)}";
   cstmt = conn.prepareCall (SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

Строковая переменная SQL представляет хранимую процедуру с параметрами-заполнителями.

Использование объектов CallableStatement очень похоже на использование объектов PreparedStatement. Вы должны привязать значения ко всем параметрам перед выполнением оператора, иначе вы получите исключение SQLException.

Если у вас есть параметры IN, просто следуйте тем же правилам и методам, которые применяются к объекту PreparedStatement; используйте метод setXXX (), который соответствует типу данных Java, который вы привязываете.

Когда вы используете параметры OUT и INOUT, вы должны использовать дополнительный метод CallableStatement, registerOutParameter (). Метод registerOutParameter () связывает тип данных JDBC с типом данных, который ожидается от хранимой процедуры.

После вызова хранимой процедуры вы извлекаете значение из параметра OUT с помощью соответствующего метода getXXX (). Этот метод преобразует извлеченное значение типа SQL в тип данных Java.

Закрытие объекта CallableStatement

Так же, как вы закрываете другой объект Statement, по той же причине вы должны также закрыть объект CallableStatement.

Простой вызов метода close () сделает эту работу. Если вы сначала закроете объект Connection, он также закроет объект CallableStatement. Однако вы всегда должны явно закрывать объект CallableStatement, чтобы обеспечить правильную очистку.

CallableStatement cstmt = null;
try {
   String SQL = "{call getEmpName (?, ?)}";
   cstmt = conn.prepareCall (SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   cstmt.close();
}

Для лучшего понимания я бы предложил изучить Callable — Пример кода .