java - example - Diferencia entre Statement y PreparedStatement
jdbc java descargar (14)
La Declaración preparada es una versión ligeramente más poderosa de una Declaración, y siempre debe ser 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
- Compilar la consulta SQL
- Planificar / optimizar la ruta de adquisición de datos.
- Ejecutar la consulta / adquisición optimizada y devolver 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 inmediatamente una optimización previa. 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 que: "¿Hay alguna otra ventaja de usar Prepared Statement?"
Se precompilan (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 sentencias de base de datos aumenta el rendimiento de la ejecución de la base de datos
Las bases de datos almacenan cachés de planes de ejecución para sentencias ejecutadas anteriormente. 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. Enunciados "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 la memoria caché.
El protocolo de comunicaciones binarias significa menos ancho de banda y llamadas de comunicaciones 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 rápidas que las operaciones de disco, que son un orden de magnitud más rápidas que las operaciones de la 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 el texto para todos los valores de parámetros proporcionados.
Proporcionan una separación más fuerte entre el código de consulta y los valores de los parámetros (en comparación con las cadenas de SQL concatenadas), mejorando la legibilidad y ayudando a los mantenedores de código a comprender rápidamente las entradas y salidas de la consulta.
En java, puede llamar a getMetadata () y getParameterMetadata () para reflejar los campos del conjunto de resultados y los campos de parámetros, respectivamente
En java, acepta inteligentemente 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 a DB () formato).
En java, acepta ARRAY de SQL, como tipo de parámetro a través del método setArray
En Java, acepta CLOB, BLOB, OutputStreams y Readers como parámetro "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 setURL, setRowId, setSQLXML y setNull.
En java, hereda todos los métodos de Statement. Hereda el método addBatch, y además permite que se agregue un conjunto de valores de parámetros para que coincida con el conjunto de comandos de SQL por lotes a través del método addBatch.
En Java, un tipo especial de PreparedStatement (la subclase CallableStatement) permite que se ejecuten los procedimientos almacenados: soporte de alto rendimiento, encapsulación, programación de procedimientos y SQL, administración / mantenimiento / ajuste de lógica de DB, y uso de lógica y características de DB propietarias.
Algunos de los beneficios de PreparedStatement over Statement son:
- PreparedStatement nos ayuda a prevenir ataques de inyección de SQL porque escapa automáticamente a los caracteres especiales.
- PreparedStatement nos permite ejecutar consultas dinámicas con entradas de parámetros.
- PreparedStatement proporciona diferentes tipos de métodos de establecimiento para establecer los parámetros de entrada para la consulta.
- PreparedStatement es más rápido que Statement. Se vuelve más visible cuando reutilizamos PreparedStatement o usamos sus métodos de procesamiento por lotes para ejecutar múltiples consultas.
- PreparedStatement nos ayuda a escribir código orientado a objetos con métodos de establecimiento, mientras que con Statement tenemos que usar la concatenación de cadenas para crear la consulta. Si hay varios parámetros para configurar, escribir Query usando concatenación de cadenas parece muy feo y propenso a errores.
Lea más sobre el tema de la inyección de SQL en http://www.journaldev.com/2489/jdbc-statement-vs-preparedstatement-sql-injection-example
Interfaz de sentencia ejecuta sentencias de SQL estático sin parámetros.
PreparedStatement
interfaz PreparedStatement
(instrucción extendida) ejecuta una instrucción SQL precompilada con / sin parámetros
Eficiente para ejecuciones repetidas.
Está precompilado por lo que es más rápido.
La declaración es estática y la declaración preparada es dinámica.
La declaración es adecuada para DDL y una declaración preparada para DML.
La declaración es más lenta, mientras que la declaración preparada es más rápida.
La declaración se utilizará para ejecutar sentencias de SQL estático y no puede aceptar parámetros de entrada.
PreparedStatement se utilizará para ejecutar sentencias de SQL muchas veces de forma dinámica. Aceptará parámetros de entrada.
La inyección de SQL se ignora en la declaración preparada, por lo que la seguridad aumenta en la declaración preparada
No se pueden hacer CLOB en una declaración.
Y: (OraclePreparedStatement) ps
No te confundas: simplemente recuerda
- La declaración se utiliza para consultas estáticas como DDL, es decir, crear, eliminar, modificar y prepareStatement se utiliza para consultas dinámicas, es decir, consulta DML.
- En Statement, la consulta no se precompila, mientras que en prepareStatement la consulta se precompila, debido a esto prepareStatement es eficiente en el tiempo.
- prepareStatement toma el argumento en el momento de la creación, mientras que Statement no toma los argumentos. Por ejemplo, si desea crear una tabla e insertar un elemento, a continuación: Cree una tabla (estática) utilizando Statement y Insertar elemento (dinámico) utilizando prepareStatement.
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 el que la misma instrucción SQL se ejecuta repetidamente con alta eficiencia. Las declaraciones preparadas son un tipo de plantilla y se utilizan por aplicación 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, compilación y optimización de esta plantilla y la almacena sin ejecutarla.
Algunos de los parámetros como, donde la cláusula no se pasa durante la creación posterior de la plantilla, envían estos parámetros al sistema de base de datos y el sistema de base de datos utiliza la plantilla 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 utilizando diferentes técnicas y protocolos.
Cuando la cantidad 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.
Según lo citado por mattjames
El uso de una declaración en JDBC debe ser 100% localizado para ser usado para DDL (ALTER, CREATE, GRANT, etc.) ya que estos son los únicos tipos de instrucciones que no pueden aceptar VARIABLES DE BIND. PreparedStatements o CallableStatements deben usarse para CADA OTRO tipo de declaración (DML, Consultas). Como estos son los tipos de declaración que aceptan variables de enlace.
Esto es un hecho, una regla, una ley: use declaraciones preparadas EN TODAS PARTES. Utilice DECLARACIONES casi en ninguna parte.
no hay mucho que añadir,
1: si desea ejecutar una consulta en un bucle (más de 1 vez), la declaració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 SQL, que solo está disponible en PreparedStatement.
PreparedStatement
es una muy buena defensa (pero no infalible) para prevenir ataques de inyección de SQL . La vinculación de los valores de los parámetros es una buena manera de protegerse contra las "pequeñas mesas de Bobby" que realizan visitas no deseadas.
Ventajas de una PreparedStatement
:
La precompilación y el almacenamiento en caché del lado de la base de datos de la declaración SQL llevan a una ejecución más rápida en general y la capacidad de reutilizar la misma instrucción SQL en batches .
Prevención automática de attacks inyección de SQL mediante el escape integrado de comillas y otros caracteres especiales. Tenga en cuenta que esto requiere que use cualquiera de los
setXxx()
PreparedStatement
setXxx()
para establecer los valorespreparedStatement = 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();
y, por lo tanto , no alinee los valores en la cadena SQL mediante concatenación de cadenas.
preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email) VALUES (''" + person.getName() + "'', ''" + person.getEmail() + "''"); preparedStatement.executeUpdate();
Facilita la configuración de objetos Java no estándar en una cadena SQL, por ejemplo,
Date
,Time
,BigDecimal
Timestamp
,BigDecimal
,InputStream
(Blob
) yReader
(Clob
). En la mayoría de esos tipos, no puede "simplemente" hacer untoString()
como lo haría en unaStatement
simple. Incluso podría refactorizarlo todo para usarPreparedStatement#setObject()
dentro de un bucle como se demuestra en el método de utilidad a continuación:public static void setValues(PreparedStatement preparedStatement, Object... values) throws SQLException { for (int i = 0; i < values.length; i++) { preparedStatement.setObject(i + 1, values[i]); } }
Que se puede utilizar de la siguiente manera:
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();
- Es mas facil de leer
- Puedes hacer que la cadena de consulta sea una constante