Cuando realizamos consultas a las bases de datos, uno de los objetos más utilizados, es el llamado PreparedStatement. Este objeto, pertenece a la interfaz Connection de la API de java, y contiene un método llamado PrepareStatement.
Este método, está sobrecargado, ya que contiene diferentes constructores. Por otro lado, veremos que al usarlo, tenemos una serie de ventajas respecto al objeto Statement.
Ventajas del uso de PreparedStatement respecto a Statement.
- Previenen los ataques de inyección SQL.
- Permiten pasar parámetros a la consulta SQL.
- Son consultas preparadas y son más rápidas. Es decir, están precompiladas y son reutilizables.
Cuando pasamos un parámetro a una consulta SQL, lo hacemos a través de un interrogante de cierre, (?). Vamos a ver un ejemplo para diferenciar los dos casos.
Una consulta SQL normal.
SELECT * FROM ventas WHERE marca = "HP"
En este caso, se seleccionan todos los campos de una tabla ventas donde el campo marca es HP.
Vamos a ahora a ver una consulta con paso de parámetros.
Consulta SQL con paso de parámetros.
SELECT * FROM ventas WHERE marca =?
Otro ejemplo seria el siguiente.
SELECT * FROM personas WHERE nombre =? AND apellidos=?
En este segundo ejemplo vemos que en lugar del valor en sí, se están utilizando interrogantes. En el primer caso, se envia un parámetro a la primera consulta. Mientras, a la segunda consulta se le están enviando 2 parámetros, ya que hay dos interrogantes.
Para utilizar el objeto PreparedStatement, lo haremos de la siguiente forma.
Conectar java con una base de datos.
Lo primero que debemos hacer es crear la conexión a nuestra base de datos. Esto lo haremos como en el ejemplo anterior. En este caso usaremos una base de datos llamada ejemplobd.
package conexion;
import java.sql.*;
/**
*
* @author Fran
* Clase encargada de conectar y desconectar de una base de datos
*/
public class Conexion {
/* Declaramos 5 variables con el driver, la bbdd, usuario y contraseña
y una para almacenar el error en caso de suceder*/
private static final String driver="com.mysql.jdbc.Driver";
private static final String bbdd="jdbc:mysql://localhost:3306/ejemplobd?useSSL=false";
private static final String usuario ="root";
private static final String clave="";
private Connection conex = null;
/**
*
* @return Devuelve la conexión a una base de datos
*/
public Connection getConexion(){
//Controlamos la excepciones que puedan surgir al conectarnos a la BBDD
try {
//Registrar el driver
Class.forName(driver);
//Creamos una conexión a la Base de Datos
conex = DriverManager.getConnection(bbdd, usuario, clave);
// Si hay errores informamos al usuario.
} catch (Exception e) {
return null;
}
// Devolvemos la conexión.
return conex;
}
}
Una vez creada la conexión, debemos tener en cuenta con que tabla vamos a trabajar. En este caso usaremos una tabla llamada ventas. De esta forma, veremos como insertar datos de diferente tipo en la base de datos.
Uso del objeto PreparedStatement.
En este ejemplo, insertaremos un registro en una tabla llamada ventas.
package conexion;
import java.sql.*;
/**
* Clase encargada de arrancar la aplicación
* @author Fran
*/
public class Principal {
// Creamos una variable String para almacenar la consulta SQL
private static String consulta="";
/**
*
* @param args Metodo principal del programa
*/
public static void main(String[] args) {
try {
// Creamos un objeto de la clase conexion.
Conexion miConexion = new Conexion();
// Si se devuelve la conexión....
if(miConexion.getConexion()!=null) {
// Usamos el método PrepareStatement del objeto Conexion
// que devuelve un objeto de tipo PreparedStatement
PreparedStatement sentencia =
miConexion.getConexion().prepareStatement(consulta);
// Creamos la consulta SQL.
consulta="Insert into ventas(producto, unidades, precio,"
+ "impuesto)values(?,?,?,?)";
// Establecemos los parametros que se van a insertar.
// El primero es de tipo texto.
sentencia.setString(1, "Refresco");
// Los tres siguientes son de tipo double,
// por lo tanto van sin comillas
sentencia.setInt(2, 6);
sentencia.setDouble(3, 5.25);
sentencia.setDouble(4, 0.21);
// Ejecutamos la consulta.
sentencia.execute(consulta);
// Mostramos un mensaje
System.out.println("Registro insertado");
}
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
Hay que tener en cuenta, que en este caso, estamos agregando valores fijos como son «rRefresco, o números como 0.21 ó 5.25. Sin embargo en su lugar podemos utilizar variables que se pueden pedir por teclado. Por ejemplo a traves de un JOptionPane o controles de una interfaz.
Por otra parte, en el caso de actualizar o eliminar registros se haría de la misma forma. Solo debemos cambiar la sentencia SQL. En caso de querer consultar registros, podemos utilizar un objeto ResultSet como hemos visto en el ejemplo anterior.