- JDBC: CallableStatement
- Создание CallableStatement
- Установка значений параметров
- Выполнение CallableStatement
- Пакетные обновления
- Параметры OUT
- Вызов функций SQL-сервера
- Batching запросов
- Хранимые процедуры Java в Java DB
- 1.1 Типы процедур Java
- Вложенные соединения
- Не вложенные соединения
- 1.2 Исключения SQL в процедурах
- 2 Создайте и используйте хранимую процедуру Java
- 2.1 Создание
- 2.1.1 Создание метода Java
JDBC: CallableStatement
Java.sql.CallableStatement используется для вызова хранимых процедур в базе данных.
Хранимая процедура похожа на функцию или метод в классе, за исключением того, что она находится в базе данных. Некоторые тяжелые операции с базой данных могут выиграть в производительности от выполнения в том же пространстве памяти, что и сервер базы данных, в качестве хранимой процедуры.
Создание CallableStatement
Вы создаете экземпляр CallableStatement, вызывая метод prepareCall() для объекта подключения. Вот пример:
CallableStatement callableStatement = connection.prepareCall("");
Если хранимая процедура возвращает ResultSet, и вам нужен ResultSet не по умолчанию(например, с другими характеристиками удерживаемости, параллелизма и т. Д.), Вам нужно будет указать эти характеристики уже при создании CallableStatement. Вот пример:
CallableStatement callableStatement = connection.prepareCall("", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_OVER_COMMIT );
Установка значений параметров
После создания CallableStatement очень похож на PreparedStatement. Например, вы можете установить параметры в SQL, в тех местах, где вы ставите? , Вот пример:
CallableStatement callableStatement = connection.prepareCall(""); callableStatement.setString(1, "param1"); callableStatement.setInt (2, 123);
Выполнение CallableStatement
После того, как вы установили значения параметров, которые вам нужно установить, вы готовы выполнить CallableStatement. Вот как это делается:
ResultSet result = callableStatement.executeQuery();
Метод executeQuery() используется, если хранимая процедура возвращает ResultSet.
Если хранимая процедура просто обновляет базу данных, вы можете вместо этого вызвать метод executeUpdate(), например:
callableStatement.executeUpdate();
Пакетные обновления
Вы можете сгруппировать несколько вызовов хранимой процедуры в пакетное обновление. Вот как это делается:
CallableStatement callableStatement = connection.prepareCall(""); callableStatement.setString(1, "param1"); callableStatement.setInt (2, 123); callableStatement.addBatch(); callableStatement.setString(1, "param2"); callableStatement.setInt (2, 456); callableStatement.addBatch(); int[] updateCounts = callableStatement.executeBatch();
Параметры OUT
Хранимая процедура может возвращать параметры OUT. То есть значения, которые возвращаются вместо ResultSet или в дополнение к нему. После выполнения CallableStatement вы можете получить доступ к этим параметрам OUT из объекта CallableStatement. Вот пример:
CallableStatement callableStatement = connection.prepareCall(""); callableStatement.setString(1, "param1"); callableStatement.setInt (2, 123); callableStatement.registerOutParameter(1, java.sql.Types.VARCHAR); callableStatement.registerOutParameter(2, java.sql.Types.INTEGER); ResultSet result = callableStatement.executeQuery(); while(result.next()) < . >String out1 = callableStatement.getString(1); int out2 = callableStatement.getInt (2);
Рекомендуется сначала обработать ResultSet, прежде чем пытаться получить доступ к любым параметрам OUT. Это рекомендуется по причинам совместимости базы данных.
Вызов функций SQL-сервера
У JDBC есть еще один интерфейс для еще более сложных сценариев. Он унаследован от PreparedStatement и называется CallableStatement .
Он используется для вызова (Call) хранимых процедур в базе данных. Особенность такого вызова в том, что кроме результата ResultSet такой хранимой процедуре можно еще и передать параметры.
А что тут нового, спросишь ты? PreparedStatement тоже имеет результат ResultSet и в него тоже можно передавать параметры. Да, все верно, но особенность хранимых процедур в том, что через параметры они могут не только получать, но и возвращать данные.
Хранимая процедура вызывается с параметрами IN, OUT и INOUT. Она возвращает один или несколько объектов ResultSet . Для создания объекта CallableStatement предназначен метод Connection.prepareCall() .
Вот представь, что у тебя есть хранимая процедура ADD, которая принимает параметры a, b и c. Эта процедура складывает a и b и помещает результат сложения в переменную с.
Давай напишем код, где попробуем ее вызвать:
// Подключение к серверу Connection connection = DriverManager.getConnection("jdbc:as400://mySystem"); // Создание объекта CallableStatement. Он выполняет предварительную обработку // вызова хранимой процедуры. Знаки вопроса // указывают, где должны быть подставлены входные параметры, а где выходные // Первые два параметра являются входными, // а третий — выходным. CallableStatement statement = connection.prepareCall("CALL MYLIBRARY.ADD (?, ?, ?)"); // Настройка входных параметров. Передаем в процедуру 123 и 234 statement.setInt (1, 123); statement.setInt (2, 234); // Регистрация типа выходного параметра statement.registerOutParameter (3, Types.INTEGER); // Запуск хранимой процедуры statement.execute(); // Получение значения выходного параметра int sum = statement.getInt(3); // Закрытие CallableStatement и Connection statement.close(); connection.close();
Работа почти как с PreparedStatement , только есть нюанс. Наша функция ADD возвращает в третьем параметре результат сложения. Только вот объект CallableStatement об этом ничего не знает. Поэтому мы говорим ему об это явно, вызвав метод registerOutParameter() :
registerOutParameter(номерПараметра, типПараметра)
После этого можно вызывать процедуру через метод execute() и затем читать данные из третьего параметра с помощью методa getInt() .
Batching запросов
В реальных проектах часто возникает ситуация, когда необходимо сделать очень много однотипных запросов (наиболее часто в этом случае встречается PreparedStatement ), например, надо вставить несколько десятков или сотен записей.
Если выполнять каждый запрос отдельно, то это займет кучу времени и снизит производительность приложения. Чтобы не допустить этого, можно использовать batch-режим вставки. Он заключается в том, что ты накапливаешь некоторый буфер своими запросами, а потом выполняешь их сразу.
В качестве примера приведу кусочек кода:
PreparedStatement stmt = con.prepareStatement( "INSERT INTO jc_contact (first_name, last_name, phone, email) VALUES (?, ?, ?, ?)"); for (int i = 0; i < 10; i++) < // Заполняем параметры запроса stmt.setString(1, "FirstName_" + i); stmt.setString(2, "LastNAme_" + i); stmt.setString(3, "phone_" + i); stmt.setString(4, "email_" + i); // Запрос не выполняется, а укладывается в буфер, // который потом выполняется сразу для всех команд stmt.addBatch(); >// Выполняем все запросы разом int[] results = stmt.executeBatch();
Вместо того, чтобы выполнять запрос методом execute() , мы складываем его в пакет с помощью метода addBatch() .
А затем, когда набралось несколько сотен запросов, можно их разом отправить на сервер, вызвав команду executeBatch() .
Полезно. Метод executeBatch() возвращает массив целых чисел — int[]. Каждая ячейка этого массива содержит число, которое означает количество строк, измененных соответствующим запросом. Если запрос номер 3 в batch’е изменил 5 строк, то 3-я ячейка массива будет содержать число 5.
Хранимые процедуры Java в Java DB
Java DB – это система управления реляционными базами данных, основанная на языке программирования Java и SQL. Это релиз Oracle проекта Apby Software Foundation с открытым исходным кодом Derby. Java DB включена в Java SE 7 SDK.
Код Java, вызываемый в базе данных, является хранимой процедурой (или процедурой). Хранимые процедуры Java являются подпрограммами JDBC (Java Database Connectivity) на стороне базы данных.
Код процедуры определяется в методе класса Java и сохраняется в базе данных. Это выполняется с использованием SQL. Код процедуры может быть с или без какого-либо кода, связанного с базой данных.
Другие программы на стороне базы данных (или на стороне сервера) являются триггерами и табличными функциями.
1.1 Типы процедур Java
Существует два типа хранимых процедур, основанных на транзакции, в которой они вызываются: вложенные соединения и не вложенные соединения.
Вложенные соединения
Процедура этого типа использует ту же транзакцию, что и оператор SQL, который ее вызвал. Код процедуры использует то же соединение, что и родительский SQL, используя синтаксис URL соединения jdbc:default:connection . Ниже приведен пример кода для получения соединения:
Обратите внимание, что атрибуты URL-адреса соединения не поддерживаются для этого типа.
Пример кода по адресу: 2.1 Создание .
Не вложенные соединения
Этот тип процедуры использует новое соединение с базой данных. Процедура выполняется в транзакции, отличной от транзакции вызывающего SQL.
Код хранимой процедуры также может подключаться к другой базе данных.
Пример кода по адресу: 3.1 Использование не вложенного соединения .
1.2 Исключения SQL в процедурах
Исключения SQL в процедурах могут быть перехвачены и обработаны в коде процедуры или распространены (и перехвачены) в вызывающей программе.
2 Создайте и используйте хранимую процедуру Java
Здесь описывается создание хранимой процедуры Java в базе данных Java DB и ее интерактивное использование в SQL, а также в коде Java. Код хранимой процедуры создается с использованием языка программирования Java. Процедура представляет собой Java-код в методе с подписью public static void procedureMethod . Хранимая процедура создается и сохраняется в базе данных Java DB как объект базы данных.
Процедура вызывается (или вызывается) с помощью команды SQL или из программы Java, использующей JDBC API.
2.1 Создание
Создайте метод Java, скомпилируйте его и сохраните процедуру в базе данных.
2.1.1 Создание метода Java
Ниже приведен пример метода.