CallableStatement
JDBC are o altă interfață pentru scenarii și mai complexe. Moștenește de la PreparedStatement și se numește CallableStatement .
Este folosit pentru a apela (Apel) procedurile stocate în baza de date. Particularitatea unui astfel de apel este că, pe lângă rezultatul ResultSet , parametrii pot fi, de asemenea, transferați unei astfel de proceduri stocate.
Ce e nou, te întrebi? PreparedStatement are, de asemenea, un rezultat ResultSet și îi puteți transmite și parametri. Da, așa este, dar particularitatea procedurilor stocate este că prin parametri pot nu numai să primească, ci și să returneze date.
Procedura stocată este apelată cu parametrii IN , OUT și INOUT . Returnează unul sau mai multe obiecte ResultSet . Metoda Connection.prepareCall() este utilizată pentru a crea un obiect CallableStatement .
Imaginați-vă că aveți o procedură ADD stocată care acceptă parametrii a, b și c. Această procedură adaugă a și b și plasează rezultatul adunării în variabila c.
Să scriem codul unde vom încerca să-l numim:
// Connect to the server
Connection connection = DriverManager.getConnection("jdbc:as400://mySystem");
// Create a CallableStatement object. It does preprocessing
// calling a stored procedure. Question marks
// indicate where the input parameters should be substituted, and where the output ones
// The first two parameters are input,
// and the third one is a day off.
CallableStatement statement = connection.prepareCall("CALL MYLIBRARY.ADD (?, ?, ?)");
// Setting up input parameters. Passing 123 and 234 to the procedure
statement.setInt (1, 123);
statement.setInt (2, 234);
// Registering the output parameter type
statement.registerOutParameter (3, Types.INTEGER);
// Run stored procedure
statement.execute();
// Get the value of the output parameter
int sum = statement.getInt(3);
// Close CallableStatement and Connection
statement.close();
connection.close();
Lucrul este aproape ca și cu PreparedStatement , doar că există o nuanță. Funcția noastră ADD returnează rezultatul adunării în al treilea parametru. Numai obiectul CallableStatement nu știe nimic despre asta. Prin urmare, îi spunem acest lucru în mod explicit apelând metoda registerOutParameter() :
registerOutParameter(parameter number, Parameter type)
După aceea, puteți apela procedura prin metoda execute() și apoi puteți citi datele din al treilea parametru folosind metoda getInt() .
Cereri de lot
În proiectele reale, apare adesea o situație când trebuie să faceți o mulțime de interogări de același tip (cea mai comună în acest caz este PreparedStatement ), de exemplu, trebuie să introduceți câteva zeci sau sute de înregistrări.
Dacă executați fiecare cerere separat, va dura mult timp și va reduce performanța aplicației. Pentru a preveni acest lucru, puteți utiliza modul de inserare în lot. Constă în faptul că acumulezi niște buffer cu cererile tale și apoi le executi imediat.
Iată o bucată de cod ca exemplu:
PreparedStatement stmt = con.prepareStatement(
"INSERT INTO jc_contact (first_name, last_name, phone, email) VALUES (?, ?, ?, ?)");
for (int i = 0; i < 10; i++) {
// Fill in the request parameters
stmt.setString(1, "FirstName_" + i);
stmt.setString(2, "LastNAme_" + i);
stmt.setString(3, "phone_" + i);
stmt.setString(4, "email_" + i);
// The request is not executed, but fits into the buffer,
// which is then executed immediately for all commands
stmt.addBatch();
}
// Execute all requests at once
int[] results = stmt.executeBatch();
În loc să executăm interogarea cu metoda execute() , o grupăm cu metoda addBatch() .
Și apoi, când există câteva sute de solicitări, le puteți trimite pe toate odată către server, apelând comanda executeBatch() .
Sănătos. Metoda executeBatch() returnează o matrice de numere întregi — int[]. Fiecare celulă din această matrice conține un număr care indică numărul de rânduri modificate de interogarea corespunzătoare. Dacă cererea numărul 3 din lot a schimbat 5 rânduri, atunci a treia celulă a matricei va conține numărul 5.