238 votes

Différence entre la déclaration et de la classe PreparedStatement

L'Instruction Préparée est un peu plus puissante version de l'Énoncé, et doit toujours être au moins aussi rapide et facile à manipuler comme un Énoncé.
L'Instruction Préparée peuvent être paramétrées

La plupart des bases de données relationnelles poignées JDBC / SQL de la requête en quatre étapes:
1.Analyser les entrants de la requête SQL
2. Compiler la requête SQL
3. /Plan d'optimiser le parcours d'acquisition de données
4. Exécuter l'optimisation de requête / d'acquérir et de renvoyer des données

Une Déclaration sera toujours passer à travers les quatre étapes ci-dessus pour chaque requête SQL envoyée à la base de données. Une Instruction Préparée, pré-exécute les étapes (1) - (3) dans le processus de l'exécution ci-dessus. Ainsi, lors de la création d'une Instruction Préparée, pré-optimisation est effectuée immédiatement. L'effet est de diminuer la charge sur le moteur de base de données au moment de l'exécution.

Maintenant, ma question est celle - ci "Est tout autre avantage de l'utilisation de l'Instruction Préparée?"

Merci À L'Avance.

209voto

BalusC Points 498232

Avantages de l' PreparedStatement:

  • La précompilation et DB la mise en cache côté de l'instruction SQL conduit à l'ensemble de la rapidité d'exécution et la possibilité de réutiliser la même instruction SQL dans les lots.

  • Automatique de la prévention de l'injection SQL attaques par builtin échapper à des citations et autres caractères spéciaux. Notez que cette fonction nécessite que vous utilisez l'un de l' PreparedStatement setXxx() méthodes pour définir les valeurs

    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();
    

    et donc ne pas inline les valeurs dans la chaîne SQL par chaîne-de la concaténation.

    preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email) VALUES ('" + person.getName() + "', '" + person.getEmail() + "'");
    preparedStatement.executeUpdate();
    
  • Facilite le réglage de la non-standard des objets Java dans une chaîne SQL, par exemple, Date, Time, Timestamp, BigDecimal, InputStream (Blob) et Reader (Clob). Sur la plupart de ces types, vous ne pouvez pas "juste" faire un toString() comme vous le feriez dans un simple Statement. Vous pourriez même refactoriser le tout à l'aide d' PreparedStatement#setObject() à l'intérieur d'une boucle, comme l'a démontré l'utilité de la méthode ci-dessous:

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

    Qui peut être utilisé comme ci-dessous:

    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();
    

53voto

Glen Best Points 11455
  1. Ils sont pré-compilé (une fois), donc plus rapide pour l'exécution répétée de SQL dynamique (où les paramètres de changement)

  2. Base de données mise en cache des requêtes amplifie DB la performance de l'exécution

    Bases de données banque de caches de plans d'exécution pour les instructions exécutées. Cela permet au moteur de base de données à réutiliser les plans pour les déclarations qui ont été exécutées précédemment. Parce que PreparedStatement utilise des paramètres, chaque fois qu'il est exécuté, il semble que le même SQL, la base de données peut réutiliser le précédent plan d'accès, la réduction de traitement. Les déclarations "inline" les paramètres dans la chaîne SQL et n'apparaissent donc pas comme le SQL à la base de données, la prévention de l'utilisation du cache.

  3. Binaire protocole de communication signifie moins de bande passante et plus rapide comms appels au serveur de base de données

    Les requêtes préparées sont normalement effectués par un non-SQL protocole binaire. Cela signifie qu'il existe moins de données dans les paquets, de sorte que les communications avec le serveur est plus rapide. En règle générale, les opérations de réseau sont d'un ordre de grandeur plus rapide que les opérations de disque qui sont d'un ordre de grandeur plus rapide que dans la mémoire de l'UC oeprations. Par conséquent, une réduction de la quantité de données envoyées sur le réseau aura un bon effet sur les performances d'ensemble.

  4. Ils protègent contre les injections SQL, par la fuite de texte pour toutes les valeurs des paramètres fournis.

  5. Ils offrent une meilleure séparation entre le code de requête et les valeurs de paramètre (par rapport à concaténées des chaînes SQL), une stimulation de la lisibilité et de l'aider code des mainteneurs de comprendre rapidement les entrées et les sorties de la requête.

  6. En java, il peut appeler getMetadata() et getParameterMetadata() pour réfléchir sur l'ensemble des résultats des champs et des champs de paramètre, respectivement

  7. En java, intelligemment accepte des objets java en tant que types de paramètres via setObject, setBoolean, setByte, setDate, setDouble, setDouble, setFloat, setInt, setLong, setShort, setTime, setTimestamp - il se transforme en JDBC de type de format qui est comprehendible DB (pas seulement toString() de format).

  8. En java, accepte SQL Tableaux, comme type de paramètre via setArray méthode

  9. En java, accepte CLOBs, Gouttes, OutputStreams et les Lecteurs comme paramètre "nourrit" via setClob/setNClob, setBlob, setBinaryStream, setCharacterStream/setAsciiStream/setNCharacterStream méthodes, respectivement

  10. En java, permet de DB-spécifique des valeurs pour la LIAISON de données SQL, SQL ROWID, SQL, XML, et la valeur NULL par setURL, setRowId, setSQLXML sna setNull méthodes

  11. En java, hérite de toutes les méthodes de Déclaration. Il hérite de la addBatch méthode, et permet en outre d'un ensemble de valeurs de paramètres pour être ajouté pour correspondre à l'ensemble des commandes SQL par lots via addBatch méthode.

  12. En java, un type spécial de PreparedStatement (la sous-classe CallableStatement) permet à des procédures stockées pour être exécutée, en soutenant la haute performance, l'encapsulation, la programmation procédurale et SQL, DB administration/maintenance/optimisation de la logique, et l'utilisation de la propriété DB logique et caractéristiques de l'

38voto

duffymo Points 188155

``est une très bonne défense (mais pas infaillible) dans la prévention des attaques par injection SQL. Les valeurs des paramètres de liaison est un bon moyen de se prémunir contre les « petites Tables Bobby » effectuer une visite indésirable.

32voto

Pankaj Points 926

Certains des avantages de PreparedStatement de Déclaration sont les suivants:

  1. PreparedStatement nous aide dans la prévention des attaques par injection SQL, car il automatiquement échappe les caractères spéciaux.
  2. PreparedStatement nous permet d'exécuter des requêtes dynamiques avec des paramètres d'entrées.
  3. PreparedStatement fournit différents types de méthodes de définition pour définir les paramètres d'entrée de la requête.
  4. PreparedStatement est plus rapide que la Déclaration. Il devient de plus en plus visible quand on réutiliser le PreparedStatement ou utiliser le traitement par lot des méthodes pour l'exécution de plusieurs requêtes.
  5. PreparedStatement nous aide dans l'écriture de code Orienté objet avec des méthodes de définition alors qu'avec la Déclaration que nous avons à utiliser la Concaténation de Chaîne pour créer la requête. Si il y a plusieurs paramètres à définir, l'écriture de la Requête en utilisant la concaténation de Chaîne est très moche et sujettes à erreur.

Lire plus sur le problème d'injection SQL à http://www.journaldev.com/2489/jdbc-statement-vs-preparedstatement-sql-injection-example

13voto

mhshams Points 3839

rien grand chose à ajouter,

1 - si vous souhaitez exécuter une requête dans une boucle (plus de 1 heure), préparée peut être plus rapide, en raison de l’optimisation que vous avez mentionnés.

2 - requête paramétrée est un bon moyen d’éviter l’Injection SQL, qui est uniquement disponible dans la classe PreparedStatement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X