JDBC - Statements, PreparedStatement e CallableStatement

Una volta ottenuta una connessione, possiamo interagire con il database. Le interfacce JDBC Statement, CallableStatement e PreparedStatement definiscono i metodi e le proprietà che consentono di inviare comandi SQL o PL / SQL e ricevere dati dal database.

Definiscono anche metodi che aiutano a colmare le differenze di tipo di dati tra i tipi di dati Java e SQL utilizzati in un database.

La tabella seguente fornisce un riepilogo dello scopo di ciascuna interfaccia per decidere quale interfaccia utilizzare.

Interfacce Uso consigliato
Dichiarazione Usalo per un accesso generico al tuo database. Utile quando si utilizzano istruzioni SQL statiche in fase di esecuzione. L'interfaccia Statement non può accettare parametri.
Discorso preparato Usalo quando prevedi di usare molte volte le istruzioni SQL. L'interfaccia PreparedStatement accetta parametri di input in fase di esecuzione.
CallableStatement Usalo quando vuoi accedere alle procedure memorizzate del database. L'interfaccia CallableStatement può anche accettare parametri di input di runtime.

Gli oggetti dell'istruzione

Creazione dell'oggetto istruzione

Prima di poter utilizzare un oggetto Statement per eseguire un'istruzione SQL, è necessario crearne uno utilizzando il metodo createStatement () dell'oggetto Connection, come nell'esempio seguente:

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

Dopo aver creato un oggetto Statement, è possibile utilizzarlo per eseguire un'istruzione SQL con uno dei suoi tre metodi di esecuzione.

  • boolean execute (String SQL): Restituisce un valore booleano true se è possibile recuperare un oggetto ResultSet; in caso contrario, restituisce false. Utilizzare questo metodo per eseguire istruzioni SQL DDL o quando è necessario utilizzare un SQL veramente dinamico.

  • int executeUpdate (String SQL): Restituisce il numero di righe interessate dall'esecuzione dell'istruzione SQL. Utilizzare questo metodo per eseguire istruzioni SQL per le quali si prevede di ottenere un numero di righe interessate, ad esempio un'istruzione INSERT, UPDATE o DELETE.

  • ResultSet executeQuery (String SQL): Restituisce un oggetto ResultSet. Utilizzare questo metodo quando si prevede di ottenere un set di risultati, come si farebbe con un'istruzione SELECT.

Oggetto istruzione di chiusura

Proprio come si chiude un oggetto Connection per salvare le risorse del database, per lo stesso motivo è necessario chiudere anche l'oggetto Statement.

Una semplice chiamata al metodo close () farà il lavoro. Se si chiude prima l'oggetto Connection, chiuderà anche l'oggetto Statement. Tuttavia, è necessario chiudere sempre esplicitamente l'oggetto Statement per garantire una corretta pulizia.

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

Per una migliore comprensione, ti suggeriamo di studiare il tutorial Dichiarazione - Esempio .

Gli oggetti PreparedStatement

L' interfaccia PreparedStatement estende l'interfaccia Statement, che offre funzionalità aggiuntive con un paio di vantaggi rispetto a un oggetto Statement generico.

Questa istruzione offre la flessibilità di fornire argomenti in modo dinamico.

Creazione dell'oggetto PreparedStatement

PreparedStatement pstmt = null;
try {
   String SQL = "Update Employees SET age = ? WHERE id = ?";
   pstmt = conn.prepareStatement(SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

Tutti i parametri in JDBC sono rappresentati dal ?simbolo, noto come indicatore di parametro. È necessario fornire valori per ogni parametro prima di eseguire l'istruzione SQL.

Il setXXX() i metodi legano i valori ai parametri, dove XXXrappresenta il tipo di dati Java del valore che si desidera associare al parametro di input. Se dimentichi di fornire i valori, riceverai una SQLException.

Ogni indicatore di parametro è indicato dalla sua posizione ordinale. Il primo indicatore rappresenta la posizione 1, la posizione successiva 2 e così via. Questo metodo è diverso da quello degli indici di array Java, che inizia da 0.

Tutti di Statement object'si metodi per interagire con il database (a) execute (), (b) executeQuery () e (c) executeUpdate () funzionano anche con l'oggetto PreparedStatement. Tuttavia, i metodi vengono modificati per utilizzare istruzioni SQL che possono immettere i parametri.

Chiusura dell'oggetto PreparedStatement

Così come chiudete un oggetto Statement, per lo stesso motivo dovreste chiudere anche l'oggetto PreparedStatement.

Una semplice chiamata al metodo close () farà il lavoro. Se si chiude prima l'oggetto Connection, verrà chiuso anche l'oggetto PreparedStatement. Tuttavia, è necessario chiudere sempre in modo esplicito l'oggetto PreparedStatement per garantire la corretta pulizia.

PreparedStatement pstmt = null;
try {
   String SQL = "Update Employees SET age = ? WHERE id = ?";
   pstmt = conn.prepareStatement(SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   pstmt.close();
}

Per una migliore comprensione, studiamo Prepare - Example Code .

Gli oggetti CallableStatement

Proprio come un oggetto Connection crea gli oggetti Statement e PreparedStatement, crea anche l'oggetto CallableStatement, che verrebbe utilizzato per eseguire una chiamata a una stored procedure di database.

Creazione dell'oggetto CallableStatement

Supponiamo di dover eseguire la seguente procedura memorizzata 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: La procedura memorizzata sopra è stata scritta per Oracle, ma stiamo lavorando con il database MySQL quindi, scriviamo la stessa procedura memorizzata per MySQL come segue per crearla nel database 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 ;

Esistono tre tipi di parametri: IN, OUT e INOUT. L'oggetto PreparedStatement utilizza solo il parametro IN. L'oggetto CallableStatement può utilizzare tutti e tre.

Ecco le definizioni di ciascuno -

Parametro Descrizione
IN Un parametro il cui valore è sconosciuto quando viene creata l'istruzione SQL. Associare i valori ai parametri IN con i metodi setXXX ().
SU Un parametro il cui valore viene fornito dall'istruzione SQL che restituisce. Si recuperano i valori dai parametri OUT con i metodi getXXX ().
DENTRO FUORI Un parametro che fornisce valori di input e output. Associate le variabili con i metodi setXXX () e recuperate i valori con i metodi getXXX ().

Il frammento di codice seguente mostra come utilizzare Connection.prepareCall() metodo per istanziare un file CallableStatement oggetto basato sulla procedura memorizzata precedente -

CallableStatement cstmt = null;
try {
   String SQL = "{call getEmpName (?, ?)}";
   cstmt = conn.prepareCall (SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

La variabile String SQL, rappresenta la stored procedure, con segnaposto di parametro.

L'utilizzo degli oggetti CallableStatement è molto simile all'utilizzo degli oggetti PreparedStatement. È necessario associare i valori a tutti i parametri prima di eseguire l'istruzione, altrimenti si riceverà una SQLException.

Se hai parametri IN, segui le stesse regole e tecniche che si applicano a un oggetto PreparedStatement; utilizzare il metodo setXXX () che corrisponde al tipo di dati Java che si sta collegando.

Quando si utilizzano i parametri OUT e INOUT, è necessario utilizzare un metodo CallableStatement aggiuntivo, registerOutParameter (). Il metodo registerOutParameter () associa il tipo di dati JDBC al tipo di dati che si prevede che la procedura memorizzata restituisca.

Dopo aver chiamato la procedura memorizzata, si recupera il valore dal parametro OUT con il metodo getXXX () appropriato. Questo metodo esegue il cast del valore recuperato del tipo SQL su un tipo di dati Java.

Chiusura dell'oggetto CallableStatement

Proprio come chiudi un altro oggetto Statement, per lo stesso motivo dovresti chiudere anche l'oggetto CallableStatement.

Una semplice chiamata al metodo close () farà il lavoro. Se chiudi prima l'oggetto Connection, chiuderà anche l'oggetto CallableStatement. Tuttavia, dovresti sempre chiudere in modo esplicito l'oggetto CallableStatement per garantire una corretta pulizia.

CallableStatement cstmt = null;
try {
   String SQL = "{call getEmpName (?, ?)}";
   cstmt = conn.prepareCall (SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   cstmt.close();
}

Per una migliore comprensione, suggerirei di studiare Callable - Example Code .