Seguí todas las respuestas de esta pregunta para cambiar un código heredado que funcionaba usando Statement
(pero con inyecciones SQL) a una solución que usaba PreparedStatement
un código mucho más lento debido a la poca comprensión de la semántica en torno a Statement.addBatch(String sql)
& PreparedStatement.addBatch()
.
Así que estoy enumerando mi escenario aquí para que otros no cometan el mismo error.
Mi escenario era
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();
Entonces, en el código anterior, tuve miles de consultas diferentes, todas agregadas a la misma declaración y este código funcionó más rápido porque las declaraciones que no se almacenaron en caché eran buenas y este código rara vez se ejecutaba en la aplicación.
Ahora para arreglar las inyecciones SQL, cambié este código a,
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();
}
Como puede ver, comencé a crear miles de PreparedStatement
objetos y, finalmente, no pude utilizar el procesamiento por lotes porque mi escenario exigía eso: hay miles de consultas ACTUALIZAR o INSERTAR y todas estas consultas son diferentes.
La reparación de la inyección SQL fue obligatoria sin costo de degradación del rendimiento y no creo que sea posible PreparedStatement
en este escenario.
Además, cuando utiliza una instalación de procesamiento por lotes incorporada, debe preocuparse por cerrar solo una Declaración, pero con este enfoque de Lista, debe cerrar la declaración antes de volver a usarla, Reutilizar una Declaración Preparada