English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

JDBC Statement, PreparedStatement и CallableStatement

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

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

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

интерфейс
Рекомендуется использовать
Statement

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

PreparedStatement

Используйте этот вариант, когда вы планируете多次 использовать SQL-поряжения. Интерфейс PreparedStatement принимает параметры ввода в режиме выполнения.

CallableStatement

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

Объект Statement

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

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

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

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

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

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

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

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

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

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

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

Чтобы лучше понять, мы рекомендуем вам изучитьПример教程 по Statement.

Объект 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.

Каждый маркер параметра ссылаются на его порядковый номер. Первый маркер represents position 1, второй represents position 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();
}

Чтобы лучше понять, давайте изучим «Пример кода PreparedStatement.

Объект 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;

NOTE: Указанная выше хранимая процедура написана для 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 может использовать все три.

Это определение каждого -

ОбластьОписание
IN

Параметры, значения которых не известны при создании SQL-выражения. Значение можно привязать к IN something с помощью метода setXXX ()

OUT

Значение параметра предоставляется возвращаемым SQL-выражением. Значение можно извлечь из параметра с помощью метода 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 к ожидаемому типу данных, возвращаемому хранимой процедурой.

После вызова хранимой процедуры можно использовать соответствующие методы getXXX() для извлечения значений из параметров OUT. Этот метод преобразует полученные значения типа 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();
}

Для лучшего понимания я рекомендую изучитьПример кода CallableStatement.