CallableStatement
JDBC ha un'altra interfaccia per scenari ancora più complessi. Eredita da PreparedStatement e viene chiamato CallableStatement .
Viene utilizzato per chiamare (Call) le procedure memorizzate nel database. La particolarità di tale chiamata è che, oltre al ResultSet result , i parametri possono anche essere passati a tale stored procedure.
Cosa c'è di nuovo, chiedi? PreparedStatement ha anche un risultato ResultSet e puoi anche passargli dei parametri. Sì, esatto, ma la particolarità delle stored procedure è che tramite parametri possono non solo ricevere, ma anche restituire dati.
La procedura memorizzata viene richiamata con i parametri IN , OUT e INOUT . Restituisce uno o più oggetti ResultSet . Il metodo Connection.prepareCall() viene utilizzato per creare un oggetto CallableStatement .
Qui immagina di avere una stored procedure ADD che accetta i parametri a, b e c. Questa procedura somma aeb e inserisce il risultato dell'addizione nella variabile c.
Scriviamo il codice dove proveremo a chiamarlo:
// 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();
Il lavoro è quasi come con PreparedStatement , solo che c'è una sfumatura. La nostra funzione ADD restituisce il risultato dell'addizione nel terzo parametro. Solo l' oggetto CallableStatement non ne sa nulla. Pertanto, glielo diciamo esplicitamente chiamando il metodo registerOutParameter() :
registerOutParameter(parameter number, Parameter type)
Successivamente, puoi chiamare la procedura tramite il metodo execute() e quindi leggere i dati dal terzo parametro utilizzando il metodo getInt() .
Richieste di dosaggio
Nei progetti reali, si verifica spesso una situazione in cui è necessario eseguire molte query dello stesso tipo (la più comune in questo caso è PreparedStatement ), ad esempio, è necessario inserire diverse decine o centinaia di record.
Se esegui ogni richiesta separatamente, ci vorrà molto tempo e ridurrai le prestazioni dell'applicazione. Per evitare ciò, è possibile utilizzare la modalità di inserimento batch. Sta nel fatto che accumuli del buffer con le tue richieste e poi le esegui immediatamente.
Ecco un pezzo di codice come esempio:
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();
Invece di eseguire la query con il metodo execute() , la eseguiamo in batch con il metodo addBatch() .
E poi, quando ci sono diverse centinaia di richieste, puoi inviarle tutte in una volta al server chiamando il comando executeBatch() .
Salutare. Il metodo executeBatch() restituisce un array di numeri interi — int[]. Ogni cella di questo array contiene un numero che indica il numero di righe modificate dalla query corrispondente. Se la richiesta numero 3 nel batch ha modificato 5 righe, la terza cella dell'array conterrà il numero 5.