J'ai suivi toutes les réponses à cette question pour changer un code hérité fonctionnant en utilisant - Statement
(mais ayant des injections SQL) en une solution utilisant PreparedStatement
avec un code beaucoup plus lent en raison d'une mauvaise compréhension de la sémantique autour de Statement.addBatch(String sql)
& PreparedStatement.addBatch()
.
Je liste donc mon scénario ici pour que les autres ne commettent pas la même erreur.
Mon scénario était
Statement statement = connection.createStatement();
for (Object object : objectList) {
//Create a query which would be different for each object
// Add this query to statement for batch using - statement.addBatch(query);
}
statement.executeBatch();
Donc, dans le code ci-dessus, j'avais des milliers de requêtes différentes, toutes ajoutées à la même instruction et ce code fonctionnait plus rapidement car les instructions non mises en cache étaient bonnes et ce code était rarement exécuté dans l'application.
Maintenant, pour corriger les injections SQL, j'ai changé ce code en,
List<PreparedStatement> pStatements = new ArrayList<>();
for (Object object : objectList) {
//Create a query which would be different for each object
PreparedStatement pStatement =connection.prepareStatement(query);
// This query can't be added to batch because its a different query so I used list.
//Set parameter to pStatement using object
pStatements.add(pStatement);
}// Object loop
// In place of statement.executeBatch(); , I had to loop around the list & execute each update separately
for (PreparedStatement ps : pStatements) {
ps.executeUpdate();
}
Donc, vous voyez, j'ai commencé à créer des milliers d' PreparedStatement
objets et je n'ai finalement pas pu utiliser le traitement par lots parce que mon scénario exigeait cela - il y a des milliers de requêtes UPDATE ou INSERT et toutes ces requêtes se trouvent être différentes.
La fixation de l'injection SQL était obligatoire sans aucun coût de dégradation des performances et je ne pense pas que ce soit possible PreparedStatement
dans ce scénario.
De plus, lorsque vous utilisez la fonction de traitement par lots intégrée, vous devez vous soucier de ne fermer qu'une seule instruction, mais avec cette approche de liste, vous devez fermer l'instruction avant de la réutiliser, Réutiliser une instruction préparée