Differenza tra Statement e PreparedStatement

L’istruzione preparata è una versione leggermente più potente di una dichiarazione e dovrebbe sempre essere altrettanto veloce e facile da gestire come una dichiarazione.
La dichiarazione preparata può essere parametrizzata

La maggior parte dei database relazionali gestisce una query JDBC / SQL in quattro passaggi:

  1. Analizzare la query SQL in entrata
  2. Compilare la query SQL
  3. Pianifica / ottimizza il percorso di acquisizione dei dati
  4. Esegui la query ottimizzata / acquisisci e restituisci i dati

Una dichiarazione procederà sempre attraverso i quattro passaggi precedenti per ogni query SQL inviata al database. Una dichiarazione preparata pre-esegue i passaggi (1) – (3) nel processo di esecuzione di cui sopra. Pertanto, quando si crea una dichiarazione preparata, viene eseguita immediatamente una pre-ottimizzazione. L’effetto è di ridurre il carico sul motore del database al momento dell’esecuzione.

Ora la mia domanda è che – “C’è qualche altro vantaggio nell’usare una dichiarazione preparata?”

Vantaggi di un PreparedStatement :

  • Precompilazione e memorizzazione nella cache lato DB dell’istruzione SQL portano a un’esecuzione complessiva più veloce e alla possibilità di riutilizzare la stessa istruzione SQL in batch .

  • Prevenzione automatica degli attacchi di SQL injection mediante l’incorporazione di escape di virgolette e altri caratteri speciali. Si noti che ciò richiede l’utilizzo di uno qualsiasi dei metodi setXxx() PreparedStatement per impostare i valori

     preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email, birthdate, photo) VALUES (?, ?, ?, ?)"); preparedStatement.setString(1, person.getName()); preparedStatement.setString(2, person.getEmail()); preparedStatement.setTimestamp(3, new Timestamp(person.getBirthdate().getTime())); preparedStatement.setBinaryStream(4, person.getPhoto()); preparedStatement.executeUpdate(); 

    e quindi non allineare i valori nella stringa SQL tramite concatenazione di stringhe.

     preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email) VALUES ('" + person.getName() + "', '" + person.getEmail() + "'"); preparedStatement.executeUpdate(); 
  • Semplifica l’impostazione di oggetti Java non standard in una stringa SQL, ad esempio Date , Time , Timestamp Date e Timestamp , BigDecimal , InputStream ( Blob ) e Reader ( Clob ). Sulla maggior parte di questi tipi non puoi “solo” fare un toString() come faresti in una semplice Statement . Si potrebbe anche rifattorizzare tutto usando il PreparedStatement#setObject() all’interno di un ciclo come dimostrato nel seguente metodo di utilità:

     public static void setValues(PreparedStatement preparedStatement, Object... values) throws SQLException { for (int i = 0; i < values.length; i++) { preparedStatement.setObject(i + 1, values[i]); } } 

    Quale può essere usato come qui sotto:

     preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email, birthdate, photo) VALUES (?, ?, ?, ?)"); setValues(preparedStatement, person.getName(), person.getEmail(), new Timestamp(person.getBirthdate().getTime()), person.getPhoto()); preparedStatement.executeUpdate(); 
  1. Sono precompilati (una volta), quindi più veloci per l’esecuzione ripetuta di SQL dinamico (dove i parametri cambiano)

  2. Il caching delle istruzioni del database aumenta le prestazioni di esecuzione del DB

    I database archiviano le cache dei piani di esecuzione per le istruzioni precedentemente eseguite. Ciò consente al motore del database di riutilizzare i piani per le istruzioni che sono state eseguite in precedenza. Poiché PreparedStatement utilizza i parametri, ogni volta che viene eseguito appare come lo stesso SQL, il database può riutilizzare il piano di accesso precedente, riducendo l’elaborazione. Le istruzioni “in linea” i parametri nella stringa SQL e quindi non appaiono come lo stesso SQL al DB, impedendo l’utilizzo della cache.

  3. Protocollo di comunicazioni binarie significa meno chiamate di larghezza di banda e comunicazioni più veloci verso il server DB

    Le istruzioni preparate vengono normalmente eseguite tramite un protocollo binario non SQL. Ciò significa che ci sono meno dati nei pacchetti, quindi le comunicazioni al server sono più veloci. Come regola generale le operazioni di rete sono un ordine di grandezza più veloce rispetto alle operazioni su disco che sono di un ordine di grandezza più veloce rispetto alle oeprations della CPU in memoria. Pertanto, qualsiasi riduzione della quantità di dati inviati attraverso la rete avrà un buon effetto sulle prestazioni complessive.

  4. Proteggono dall’iniezione SQL, eseguendo l’escape del testo per tutti i valori dei parametri forniti.

  5. Forniscono una maggiore separazione tra il codice della query e i valori dei parametri (rispetto alle stringhe SQL concatenate), aumentando la leggibilità e aiutando i manutentori del codice a comprendere rapidamente gli input e gli output della query.

  6. In java, puoi chiamare getMetadata () e getParameterMetadata () per riflettere rispettivamente sui campi del set di risultati e sui campi dei parametri

  7. In java, accetta intelligentemente oggetti java come tipi di parametri tramite setObject, setBoolean, setByte, setDate, setDouble, setDouble, setFloat, setInt, setLong, setShort, setTime, setTimestamp – converte in formato di tipo JDBC comprensibile a DB (non solo aString) () formato).

  8. In java, accetta gli ARRAY SQL, come tipo di parametro tramite il metodo setArray

  9. In java, accetta CLOB, BLOB, OutputStreams e Readers come parametri “feed” tramite setClob / setNClob, setBlob, setBinaryStream, setCharacterStream / setAsciiStream / setNCharacterStream, rispettivamente

  10. In Java, consente di impostare valori specifici per DB per SQL DATALINK, SQL ROWID, SQL XML e NULL tramite setURL, setRowId, setSQLXML e metodi setNull

  11. In java, eredita tutti i metodi dall’istruzione. Esso eredita il metodo addBatch e consente inoltre di aggiungere un set di valori di parametro per far corrispondere il set di comandi SQL batch tramite il metodo addBatch.

  12. In Java, un tipo speciale di PreparedStatement (la sottoclass CallableStatement) consente l’esecuzione di stored procedure, supportando alte prestazioni, incapsulamento, programmazione procedurale e SQL, amministrazione / manutenzione / tweaking della logica, utilizzo di logica proprietaria DB e funzionalità

PreparedStatement è un’ottima difesa (ma non infallibile) nella prevenzione degli attacchi SQL injection . I valori dei parametri vincolanti sono un buon modo per difendersi dai “piccoli tavoli Bobby” che fanno una visita indesiderata.

Alcuni dei vantaggi di PreparedStatement over Statement sono:

  1. PreparedStatement ci aiuta a prevenire attacchi di SQL injection perché sfugge automaticamente ai caratteri speciali.
  2. PreparedStatement ci consente di eseguire query dinamiche con input di parametri.
  3. PreparedStatement fornisce diversi tipi di metodi setter per impostare i parametri di input per la query.
  4. PreparedStatement è più veloce di Statement. Diventa più visibile quando riutilizziamo PreparedStatement o usiamo i suoi metodi di elaborazione batch per l’esecuzione di più query.
  5. PreparedStatement ci aiuta nella scrittura di codice orientato agli oggetti con metodi setter mentre con Statement dobbiamo utilizzare String Concatenation per creare la query. Se sono presenti più parametri da impostare, la scrittura di query utilizzando la concatenazione di stringhe risulta molto brutta e soggetta a errori.

Maggiori informazioni sul problema dell’iniezione SQL all’indirizzo http://www.journaldev.com/2489/jdbc-statement-vs-preparedstatement-sql-injection-example

niente da aggiungere,

1 – se vuoi eseguire una query in un ciclo (più di una volta), l’istruzione preparata può essere più veloce, a causa dell’ottimizzazione che hai menzionato.

2 – La query parametrizzata è un buon metodo per evitare SQL Injection, che è disponibile solo in PreparedStatement.

La dichiarazione è statica e la statica preparata è dynamic.

La dichiarazione è adatta per DDL e statuto preparato per DML.

La dichiarazione è più lenta mentre la dichiarazione preparata è più veloce.

più differenze

Non posso fare CLOB in una dichiarazione.

E: (OraclePreparedStatement) ps

SQL injection viene ignorato dalla dichiarazione preparata, quindi la sicurezza è un aumento nella dichiarazione preparata

Come citato da Mattjames

L’uso di una dichiarazione in JDBC deve essere localizzato al 100% per essere utilizzato per DDL (ALTER, CREATE, GRANT, ecc.) Poiché questi sono gli unici tipi di istruzione che non possono accettare VARIABILI DI BIND. PreparedStatements o CallableStatements devono essere utilizzati per OGNI ALTRO tipo di istruzione (DML, Query). Poiché questi sono i tipi di istruzione che accettano variabili di bind.

Questo è un fatto, una regola, una legge – usa le dichiarazioni preparate OVUNQUE. Utilizzare le dichiarazioni quasi senza dove.

  • È più facile da leggere
  • Puoi facilmente rendere la stringa di query una costante

L’istruzione verrà utilizzata per l’esecuzione di istruzioni SQL statiche e non può accettare parametri di input.

PreparedStatement verrà utilizzato per l’esecuzione di istruzioni SQL più volte in modo dinamico. Accetterà i parametri di input.

Un’altra caratteristica della query preparata o parametrizzata: riferimento tratto da questo articolo.

Questa dichiarazione è una delle funzionalità del sistema di database in cui la stessa istruzione SQL viene eseguita ripetutamente con alta efficienza. Le istruzioni preparate sono un tipo di modello e utilizzate dall’applicazione con parametri diversi.

Il modello di istruzione viene preparato e inviato al sistema di database e il sistema di database esegue analisi, compilazione e ottimizzazione su questo modello e memorizza senza eseguirlo.

Alcuni dei parametri come, la clausola where non viene passata durante la creazione del modello dell’applicazione successiva, inviare questi parametri al sistema di database e al modello di utilizzo del sistema di database di SQL Statement ed eseguito come da richiesta.

Le istruzioni preparate sono molto utili contro SQL Injection perché l’applicazione può preparare parametri utilizzando tecniche e protocolli diversi.

Quando il numero di dati aumenta e gli indici cambiano di frequente in quel momento, le istruzioni preparate potrebbero non riuscire perché in questa situazione è necessario un nuovo piano di query.

Statement interfaccia Statement esegue istruzioni SQL statiche senza parametri

PreparedStatement interfaccia PreparedStatement (extending Statement) esegue un’istruzione SQL precompilata con / senza parametri

  1. Efficiente per esecuzioni ripetute

  2. È precompilato quindi è più veloce

Non ottenere confusione: semplicemente ricorda

  1. L’istruzione viene utilizzata per query statiche come DDL, ad esempio crea, rilascia, modifica e prepareStatement viene utilizzato per query dinamiche, ad esempio query DML.
  2. In Statement, la query non è precompilata mentre nella query prepareStatement è precompilata, in quanto preparationTatement è efficiente in termini di tempo.
  3. prepareStatement accetta argomenti al momento della creazione mentre Statement non accetta argomenti. Ad esempio se si desidera creare una tabella e inserire un elemento quindi: Creare tabella (statica) utilizzando l’elemento Istruzione e Inserisci (dinamico) utilizzando prepareStatement.