Forum Programmation.java Bon usage de PreparedStatement

Posté par .
Tags : aucun
1
18
jan.
2011
Je pensais qu'il fallait, a des fins d'optimisation, conserver les requêtes SQL sous forme de PreparedStatement, or je trouve plein d'exemples comme celui-ci sur le web :


public void update(Account entity) throws Exception {
try {
Connection conn = base.getConnection();
PreparedStatement stmt = conn.prepareStatement("update Accounts set Description = ? where Id = ?");
stmt.setString(1,entity.getDescription());
stmt.setInt(2, entity.getId());
stmt.executeUpdate();
stmt.close();
}
catch (SQLException e) {
throw e;
}
}


La requête SQL est repréparée à chaque appel de la méthode update ?
  • # Pas le principal intérêt

    Posté par (page perso) . Évalué à 5.

    L'intérêt d'un PreparedStatement est en effet que la requête est compilée coté SGBD et donc que si elle est lancée plusieurs fois avec divers arguments on gagne en performance.

    Mais c'est oublié l'autre intérêt et le plus important à mon avis : la sécurité.
    L'utilisation (correcte) de PreparedStatement évite les injections SQL. C'est pour cela qu'il faut toujours en utiliser quand un paramètre doit être passé en argument à ta requête même si tu ne l'utiliseras qu'une fois.

    Cf. http://xkcd.com/327/

    L'association LinuxFr ne saurait être tenue responsable des propos légalement repréhensibles ou faisant allusion à l'évêque de Rome, au chef de l'Église catholique romaine ou au chef temporel de l'État du Vatican et se trouvant dans ce commentaire

    • [^] # Re: Pas le principal intérêt

      Posté par . Évalué à 0.

      Il n'y a pas que les Webappli dans la vie ! Dans mon cas, la base de données réside sur le poste client et peut être ouverte avec OpenOffice.

      Mon questionnement portait sur l'absence d'optimisation dans ce type de code.
      • [^] # Re: Pas le principal intérêt

        Posté par (page perso) . Évalué à 3.

        Qui a parlé d'applications web ? L'injection SQL c'est aussi possible avec une application "lourde".

        L'association LinuxFr ne saurait être tenue responsable des propos légalement repréhensibles ou faisant allusion à l'évêque de Rome, au chef de l'Église catholique romaine ou au chef temporel de l'État du Vatican et se trouvant dans ce commentaire

  • # Ça dépends (ça dépasse)

    Posté par . Évalué à 2.

    Effectivement, en toute logique la requête est re-préparée à chaque exécution, ce qui fait perdre le gain à ne compiler qu'une seule fois la requête.

    En pratique au moins deux des deux SGBD les plus populaires compensent les erreurs des développeurs et les manques d'un certain langage de web dynamique de 3 lettres commençant par P en gérant un cache des dernières requêtes exécutés, ce qui évite d'avoir à recompiler la requête à chaque fois.
  • # thread safe

    Posté par . Évalué à 2.

    L'envie est grande en effet de préparer la requête paramétrée une bonne fois pour toute en amont et de ne garder dans la méthode que le remplissage des paramètres et l'exécution. cela paraît plus optimal.
    Mais, rien ne garanti que l'implémentation, fournie par le driver jdbc, est thread safe et donc que le PreparedStatement peut être utilisé en environnement multi-threadé.
    si tu es sur que ton exécution est mono-threadé, tu peux éventuellement faire cette optimisation. mais:
    1/ tu prends un risque sur la maintenabilité de ton application: passage en multi-threadé impossible sans refacto, ou, plus surement, bug lors du passage en multi-threadé en ayant oublié cette limitation.
    2/ ton optimisation ne sert surement à rien pour la plupart des implémentations (oracle en tête).
    Bref, à peser le pour et le contre.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.