La Declaración preparada es una versión un poco más poderosa de una Declaración, y siempre debe ser al menos tan rápida y fácil de manejar como una Declaración.
La declaración preparada puede ser parametrizada
La mayoría de las bases de datos relacionales manejan una consulta JDBC / SQL en cuatro pasos:
- Analizar la consulta SQL entrante
- Compile la consulta SQL
- Planifique / optimice la ruta de adquisición de datos
- Ejecute la consulta / adquisición optimizada y devuelva datos
Una declaración siempre procederá a través de los cuatro pasos anteriores para cada consulta SQL enviada a la base de datos. Una declaración preparada ejecuta previamente los pasos (1) - (3) en el proceso de ejecución anterior. Por lo tanto, al crear una declaración preparada, se realiza una optimización previa de inmediato. El efecto es disminuir la carga en el motor de la base de datos en el momento de la ejecución.
Ahora mi pregunta es: "¿Hay alguna otra ventaja de usar la Declaración preparada?"
Respuestas:
Ventajas de a
PreparedStatement
:La precompilación y el almacenamiento en caché del lado DB de la instrucción SQL conduce a una ejecución general más rápida y a la capacidad de reutilizar la misma instrucción SQL en lotes .
Prevención automática de ataques de inyección SQL mediante escape integrado de comillas y otros caracteres especiales. Tenga en cuenta que esto requiere que utilice cualquiera de los métodos para establecer los valores
PreparedStatement
setXxx()
y, por lo tanto , no alinee los valores en la cadena SQL concatenando cadenas.
Facilita la configuración de los objetos de Java no estándar en una cadena SQL, por ejemplo
Date
,Time
,Timestamp
,BigDecimal
,InputStream
(Blob
) yReader
(Clob
). En la mayoría de esos tipos no puede "simplemente" hacertoString()
lo que haría de una manera simpleStatement
. Incluso podría refactorizarlo todo para usarloPreparedStatement#setObject()
dentro de un ciclo como se demuestra en el siguiente método de utilidad:Que se puede usar de la siguiente manera:
fuente
Statement
, pero puede valer la pena una prueba.Están precompilados (una vez), por lo que son más rápidos para la ejecución repetida de SQL dinámico (donde los parámetros cambian)
El almacenamiento en caché de instrucciones de la base de datos aumenta el rendimiento de ejecución de la base de datos
Las bases de datos almacenan cachés de planes de ejecución para declaraciones ejecutadas previamente. Esto permite que el motor de la base de datos reutilice los planes para las declaraciones que se han ejecutado anteriormente. Debido a que PreparedStatement usa parámetros, cada vez que se ejecuta aparece como el mismo SQL, la base de datos puede reutilizar el plan de acceso anterior, lo que reduce el procesamiento. Las declaraciones "en línea" los parámetros en la cadena SQL y, por lo tanto, no aparecen como el mismo SQL en la base de datos, lo que impide el uso de caché.
El protocolo de comunicaciones binarias significa menos ancho de banda y llamadas de comunicación más rápidas al servidor DB
Las declaraciones preparadas normalmente se ejecutan a través de un protocolo binario no SQL. Esto significa que hay menos datos en los paquetes, por lo que las comunicaciones con el servidor son más rápidas. Como regla general, las operaciones de red son un orden de magnitud más lento que las operaciones de disco, que son un orden de magnitud más lento que las operaciones de CPU en memoria. Por lo tanto, cualquier reducción en la cantidad de datos enviados a través de la red tendrá un buen efecto en el rendimiento general.
Protegen contra la inyección de SQL, escapando texto para todos los valores de parámetros proporcionados.
Proporcionan una separación más fuerte entre el código de la consulta y los valores de los parámetros (en comparación con las cadenas SQL concatenadas), aumentan la legibilidad y ayudan a los mantenedores de códigos a comprender rápidamente las entradas y salidas de la consulta.
En java, puede llamar a getMetadata () y getParameterMetadata () para reflexionar sobre los campos del conjunto de resultados y los campos de parámetros, respectivamente
En java, acepta de forma inteligente los objetos java como tipos de parámetros a través de setObject, setBoolean, setByte, setDate, setDouble, setDouble, setFloat, setInt, setLong, setShort, setTime, setTimestamp: se convierte en formato de tipo JDBC que es comprensible para DB (no solo para String) () formato).
En java, acepta los ARRAY SQL, como tipo de parámetro mediante el método setArray
En java, acepta CLOBs, BLOBs, OutputStreams y Readers como parámetros "feeds" a través de los métodos setClob / setNClob, setBlob, setBinaryStream, setCharacterStream / setAsciiStream / setNCharacterStream, respectivamente
En java, permite establecer valores específicos de DB para SQL DATALINK, SQL ROWID, SQL XML y NULL a través de los métodos setURL, setRowId, setSQLXML y setNull
En java, hereda todos los métodos de Statement. Hereda el método addBatch y, además, permite agregar un conjunto de valores de parámetros para que coincida con el conjunto de comandos SQL por lotes a través del método addBatch.
En java, un tipo especial de PreparedStatement (la subclase CallableStatement) permite la ejecución de procedimientos almacenados, lo que admite un alto rendimiento, encapsulación, programación de procedimientos y SQL, administración / mantenimiento / ajuste de DB de lógica y uso de lógica y características de DB patentadas
fuente
Connection.createStatement
yConnection.prepareStatement
. Este diseño lo obliga a trabajar contra interfaces, por lo que no necesita conocer las clases de implementación específicas y evitar un acoplamiento estrecho innecesario con tales clases de implementación. Todo explicado con ejemplos en los documentos Java jdbc y documentos Java. :)PreparedStatement
es una muy buena defensa (pero no infalible) para prevenir ataques de inyección SQL . La vinculación de los valores de los parámetros es una buena manera de protegerse contra "pequeñas Bobby Tables" que realizan una visita no deseada.fuente
ORDER BY
) y / o constantes numéricas en ciertos lugares (pensarLIMIT
,OFFSET
y otras soluciones de paginación), por lo que estos pueden ser atacados por inyección de SQL, incluso cuando Sentencias preparadas y parametrización se utiliza siempre que sea posible.Algunos de los beneficios de PreparedStatement over Statement son:
Lea más sobre el problema de inyección SQL en http://www.journaldev.com/2489/jdbc-statement-vs-preparedstatement-sql-injection-example
fuente
no hay mucho que agregar
1: si desea ejecutar una consulta en un bucle (más de 1 vez), la instrucción preparada puede ser más rápida debido a la optimización que mencionó.
2: la consulta parametrizada es una buena manera de evitar la inyección de SQL. Las consultas parametrizadas solo están disponibles en PreparedStatement.
fuente
La declaración es estática y la declaración preparada es dinámica.
La declaración es adecuada para DDL y la declaración preparada para DML.
La declaración es más lenta mientras que la declaración preparada es más rápida.
más diferencias (archivado)
fuente
No se pueden hacer CLOB en una declaración.
Y: (OraclePreparedStatement) ps
fuente
Citado por mattjames
fuente
la inyección preparada ignora la inyección sql, por lo que la seguridad aumenta en la declaración preparada
fuente
fuente
La instrucción se usará para ejecutar instrucciones SQL estáticas y no puede aceptar parámetros de entrada.
PreparedStatement se usará para ejecutar sentencias SQL muchas veces dinámicamente. Aceptará parámetros de entrada.
fuente
Otra característica de la consulta preparada o parametrizada: referencia tomada de este artículo.
Esta declaración es una de las características del sistema de base de datos en la que la misma declaración SQL se ejecuta repetidamente con alta eficiencia. Las declaraciones preparadas son un tipo de plantilla y son utilizadas por aplicaciones con diferentes parámetros.
La plantilla de declaración se prepara y se envía al sistema de base de datos y el sistema de base de datos realiza el análisis, la compilación y la optimización de esta plantilla y la almacena sin ejecutarla.
Algunos parámetros como, cuando la cláusula no se pasa durante la aplicación posterior de creación de plantilla, envían estos parámetros al sistema de base de datos y la plantilla de uso de la base de datos de la Declaración SQL y se ejecuta según la solicitud.
Las declaraciones preparadas son muy útiles contra la inyección de SQL porque la aplicación puede preparar parámetros usando diferentes técnicas y protocolos.
Cuando el número de datos aumenta y los índices cambian con frecuencia en ese momento, las declaraciones preparadas pueden fallar porque en esta situación se requiere un nuevo plan de consulta.
fuente
Statement
la interfaz ejecuta sentencias SQL estáticas sin parámetrosPreparedStatement
La interfaz (declaración de extensión) ejecuta una declaración SQL precompilada con / sin parámetrosEficiente para ejecuciones repetidas
Está precompilado por lo que es más rápido.
fuente
No te confundas: simplemente recuerda
fuente
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 usabaPreparedStatement
un código mucho más lento debido a la poca comprensión de la semántica en torno aStatement.addBatch(String sql)
&PreparedStatement.addBatch()
.Así que estoy enumerando mi escenario aquí para que otros no cometan el mismo error.
Mi escenario era
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,
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
fuente