1. CallableStatement
У 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() і потім читати дані з третього параметра за допомогою методу getInt ().
2. 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.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ