martes, 6 de diciembre de 2016

LA CLASE PREPAREDSTATEMENT EN JAVA



La clase PreparedStatement: 
1.      CONTENIDO:

DEFICICION:
La interfase PreparedStatement hereda de Statement y se diferencia de esta de dos maneras.
• Las instancias de PreparedStatement contienen una sentencia SQL que ya ha sido compilada. Esto es lo que hace que se le llame ‘prepared’ (preparada).
• La sentencia SQL contenida en un objeto PreparedStatement pueden tener uno o más parámetros IN (entrada). Un parámetro de entrada es aquel cuyo valor no se especifica en la sentencia SQL cuando se crea; en vez de ello la sentencia tiene un interrogante (‘?’) como un ‘encaje’ para cada parámetro de entrada. Antes de ejecutarse la sentencia se debe suministrar un valor para cada interrogante mediante los métodos apropiados setXXX, que son añadidos por el interfaz PreparedStatement.
Debido a que los objetos PreparedStatement están precompilados, su ejecución será más rápida que de los objetos Statement. Por lo tanto, a una sentencia SQL que se le va a ejecutar constantemente, se le suele crear como PreparedStatement para incrementar su eficacia.
Siendo una subclase de la interfaz Statement, el interfaz PreparedStatement hereda toda la funcionalidad del interfaz Statement. Además, se añade un set completo de métodos necesarios para fijar los valores que van a ser enviados a la base de datos en el lugar de los ‘encajes’ para los parámetros de entrada. También se modifican los tres métodos execute, executeQuery y executeUpdate de tal forma que no toman argumentos. Los formatos de Statement de estos métodos (los formatos que toman una sentencia SQL como argumento) no deberían usarse nunca con objetos PreparedStatement. 
·              METODO ExecuteUpdate()
Ejecuta la instrucción SQL determinada, que puede ser una instrucción INSERT, UPDATE o DELETE; o una instrucción SQL que no devuelve nada, como una instrucción DDL de SQL.
ü Sintaxis:
 
public int executeUpdate(java.lang.String sql) 

ü Parámetros:

sql
Un objeto String que contiene la instrucción SQL.

ü Valor devuelto

Un valor int que indica el número de filas afectadas o 0 si se usa una instrucción DDL.

·              USO DE CallableStatement:
Este interfaz hereda del interfaz PreparedStatement y ofrece la posibilidad de manejar parámetros de salida y de realizar llamadas a procedimientos almacenados de la base de datos (ultimo tipo de sentencias a utilizar en JDBC).

Un objeto CallableStatement ofrece la posibilidad de realizar llamadas a procedimientos almacenados de una forma estándar para todos los DBMS. Un procedimiento almacenado se encuentra dentro de una base de datos; la llamada a un procedimiento es lo que contiene un objeto CallableStatement. Esta llamada está escrita con una sintaxis de escape, esta sintaxis puede tener dos formas diferentes: una con un parámetro de resultado, es un tipo de parámetro de salida que representa el valor devuelto por el procedimiento y otra sin ningún parámetro de resultado. Ambas formas pueden tener un número variable de parámetros de entrada, de salida o de entrada/salida. Una interrogación representará al parámetro.

La sintaxis para realizar la llamada a un procedimiento almacenado es la siguiente:
{call nombre_del_procedimiento[(?,?,...)]}
Si devuelve un parámetro de resultado:
{?=call nombre_del_procedimiento[(?.?...)]}
La sintaxis de una llamada a un procedimiento sin ningún tipo de parámetros sería:
{call nombre_del_procedimiento}

·              EJEMPLOS:
Este es un ejemplo de utilización del método executeQuery de un objeto PreparedStatement para obtener un ResultSet.
import java.sql.*;
import java.util.Properties;

public class PreparedStatementExample {

    public static void main(java.lang.String[] args)
    {
        // Cargar lo siguiente desde un objeto de propiedades.
        String DRIVER = "com.ibm.db2.jdbc.app.DB2Driver";
        String URL    = "jdbc:db2://*local";

        // Registrar el controlador JDBC nativo. Si el controlador no puede
        // registrarse, la prueba no puede continuar.
        try {
            Class.forName(DRIVER);
        } catch (Exception e) {
            System.out.println("Imposible registrar el controlador.");
            System.out.println(e.getMessage());
            System.exit(1);
        }

        Connection c = null;
        Statement s = null;

        //    Este programa crea una tabla que
        //    las sentencias preparadas utilizan más tarde.
        try {
            // Crear las propiedades de conexión.
            Properties properties = new Properties ();
            properties.put ("user", "userid");
            properties.put ("password", "password");

            // Conectar con la base de datos local de iSeries.
            c = DriverManager.getConnection(URL, properties);

            // Crear un objeto Statement.
            s = c.createStatement();
            // Se suprime la tabla de prueba, si existe. Observe que
            // en todo este ejemplo se presupone que la colección
            // MYLIBRARY existe en el sistema.
            try {
                s.executeUpdate("DROP TABLE MYLIBRARY.MYTABLE");
            } catch (SQLException e) {
                // Se continúa simplemente... es probable que la tabla no exista.
            }

            // Se ejecuta una sentencia SQL que crea una tabla en la base de datos.
            s.executeUpdate("CREATE TABLE MYLIBRARY.MYTABLE (NAME VARCHAR(20), ID INTEGER)");

        } catch (SQLException sqle) {
            System.out.println("El proceso de base de datos ha fallado.");
            System.out.println("Razón: " + sqle.getMessage());
        } finally {
            // Se cierran los recursos de base de datos.
            try {
                if (s != null) {
                    s.close();
                }
            } catch (SQLException e) {
                System.out.println("El borrado no ha podido cerrar Statement.");
}
        }


        //    A continuación, este programa utiliza una sentencia preparada para
        //    insertar muchas filas en la base de datos.
        PreparedStatement ps = null;
        String[] nameArray = {"Rich", "Fred", "Mark", "Scott", "Jason",
            "John", "Jessica", "Blair", "Erica", "Barb"};
        try {
            // Crear un objeto PreparedStatement utilizado para insertar datos en la
            // tabla.
            ps = c.prepareStatement("INSERT INTO MYLIBRARY.MYTABLE (NAME, ID) VALUES (?, ?)");

            for (int i = 0; i < nameArray.length; i++) {
                ps.setString(1, nameArray[i]);  // Se establece el nombre a partir de nuestra matriz.
                ps.setInt(2, i+1);              // Se establece el ID.
                ps.executeUpdate();
            }

        } catch (SQLException sqle) {
            System.out.println("El proceso de base de datos ha fallado.");
            System.out.println("Razón: " + sqle.getMessage());
        } finally {
            // Se cierran los recursos de base de datos.
            try {
                if (ps != null) {
                    ps.close();
                }
            } catch (SQLException e) {
                System.out.println("El borrado no ha podido cerrar Statement.");
}
        }


        //    Utilizar una sentencia preparada para consultar la tabla de
        //    base de datos que se ha creado y devolver datos desde ella. En
        //    este ejemplo, el parámetro utilizado se ha establecido de manera arbitraria
        //    en 5, lo que implica devolver todas las filas en las que el campo ID sea
        //    igual o menor que 5.
        try {
            ps = c.prepareStatement("SELECT * FROM MYLIBRARY.MYTABLE " +
                                    "WHERE ID <= ?");

            ps.setInt(1, 5);

            // Se ejecuta una consulta SQL en la tabla.
            ResultSet rs = ps.executeQuery();
            // Visualizar todos los datos de la tabla.
            while (rs.next()) {
                System.out.println("El empleado " + rs.getString(1) + " tiene el ID " + rs.getInt(2));
            }

        } catch (SQLException sqle) {
            System.out.println("El proceso de base de datos ha fallado.");
            System.out.println("Razón: " + sqle.getMessage());
        } finally {
            // Se cierran los recursos de base de datos.
            try {
                if (ps != null) {
                    ps.close();
                }
            } catch (SQLException e) {
                System.out.println("El borrado no ha podido cerrar Statement.");
}

            try {
                if (c != null) {
                    c.close();
                }
            } catch (SQLException e) {
                System.out.println("El borrado no ha podido cerrar Connection.");
}

        }
    }
}

ü  Ejemplo de PreparedStatement de consulta
Por ejemplo supongamos que hay un campo de texto en el que el usuario puede introducir su dirección de correo electrónico y con este dato se desea buscar al usuario:
Connection con = DriverManager.getConnection(url);
String consulta = "SELECT usuario FROM registro WHERE email like ?";
PreparedStatement pstmt = con.prepareStatement(consulta);
pstmt.setString(1 , campoTexto.getText());
ResultSet resultado = ps.executeQuery();
Ejemplo de PreparedStatement de modificación
En el siguiente ejemplo se va a insertar un nuevo registro en una tabla:
Connection con = DriverManager.getConnection(url);
String insercion = "INSERT INTO registro(usuario , email , fechaNac) values ( ? , ? , ? )");
PreparedStatement pstmt = con.prepareStatement(consulta);
String user = . . . ;
String email = . . . ;
Date edad = . . . ; //O int edad;
pstmt.setString(1 , user);
pstmt.setString(2 , email);
pstmt.setDate(3 , edad); // setInt(3, edad);
ps.executeUpdate();

·         El siguiente fragmento de código, donde con es un objeto Connection, crea un objeto PreparedStatement que contiene una instrucción SQL:
//Creamos un objeto PreparedStatement desde el objeto Connection
PreparedStatement ps = con.prepareStatement(
"select * from Propietarios where DNI=? AND NOMBRE=? AND EDAD=?");
//Seteamos los datos al prepared statement de la siguiente forma:
ps.setString(1, dni);
ps.setString(2, nombre);
ps.setInt(3, edad);

//Ejecutamos el PreparedStatement, en este caso con executeQuery()
ResultSet rs= ps.executeQuery();

2. Este es un ejemplo de utilización del método executeUpdate del objeto Statement.
import java.sql.*;
import java.util.Properties;
public class StatementExample {

    public static void main(java.lang.String[] args)
    {

        // Sugerencia: cargarlos desde un objeto de propiedades.

2.       RESUMEN:
El interfaz PreparedStatement hereda del interfaz Statement y se diferencia de eelo de dos maneras:
·         Las instancias de PreparedStatement contienen una sentencia SQL que ya ha sido compilada. Esto es lo que hace que se le llame ‘prepared’ (preparada).
·         La sentencia SQL contenida en un objeto PreparedStatement pueden tener uno o más parámetros IN (entrada).

Esta interfaz nos permite ejecutar sentencias SQL sobre una conexión establecida con una base de datos. pero en ella se ejecutan sentencias SQL más especializadas, estas sentencias SQL se van a denominar sentencias SQL precompiladas y van a recibir parámetros de entrada lo cual hace más rápido su ejecución que de los objetos Statement .

3.       SUMMary:

The PreparedStatement interface inherits from the Statement interface and differs from it in two ways:
• The PreparedStatement instances contain an SQL statement that has already been compiled. This is what causes it to be called 'prepared'.
• The SQL statement contained in a PreparedStatement object can have one or more IN parameters.

This interface allows us to execute SQL statements on a connection established with a database. But it runs more specialized SQL statements, these SQL statements are going to be called precompiled SQL statements and will receive input parameters which makes their execution faster than the Statement objects.

4.       RECOMENDACIONES:
Cuando trabajamos con una base de datos es posible que haya sentencias SQL que tengamos que ejecutar varias veces durante la sesión, aunque sea con distintos parámetros. Por ejemplo, durante una sesión con base de datos podemos querer insertar varios registros en una tabla. Cada vez los datos que insertamos serán distintos, pero la sentencia SQL será la misma: Un INSERT sobre determinada tabla que será simpre igual, salvo los valores concretos que queramos insertar.
Para poder ejecutar un objeto PreparedStatement, primero hay que establecer un valor en cada uno de los marcadores de parámetro. El objeto PreparedStatement proporciona varios métodos para establecer parámetros. Todos ellos tienen el formato set<Tipo>, siendo <Tipo> un tipo de datos Java. Ejemplos de estos métodos son setInt, setLong, setString, setTimestamp y setBlob. 
Se utiliza el método prepareStatement() de Connection para crear nuevos objetos PreparedStatement. A diferencia de lo que sucedía con los objetos Statement, la sentencia SQL se suministra en el momento de crear el objeto PreparedStatement. En ese momento, se precompila la sentencia SQL. 

5.       Conclusiones
Permite realizar operaciones (consultas, actualizaciones, ...) sobre bases de datos relacionales utilizando SQL (Structured Query Language).
La ejecucion de sentencias en la base de datos a traves de JDBC se realiza mediante las interfaces Statement o PreparedStatement.
Para obtener un objeto del tipo Statement se llama al metodo createStatement() del objeto Connection.
La interfaz PreparedStatement extiende a la interfaz Statement y utiliza una plantilla para crear la sentencia SQL. Se utiliza en aquellas situaciones en las que se necesita ejecutar varias veces una consulta en la que pueden cambiar ´unicamente los par´ametros. De esta forma (si el SGBD lo permite) se optimiza la consulta una sola vez.
A la hora de obtener tanto un Statement como un PreparedStatement es posible especificar (si la base de datos lo acepta) el tipo de desplazamiento deseado y si se desea que las modificaciones en el resultado se reflejen en la base de datos.

6.       APRECIACION DEL EQUIPO
Al realizar este trabajo se ha entendido acerca de cómo y cuándo usar  preparedstetment también se ha comprendido que para enviar sentencias sql. Una Prepared Statement es una sentencia SQL de base de datos precompilada. Al estar precompilada, su ejecución será más rápida que una SQL normal, por lo que es adecuada cuando vamos a ejecutar la misma sentencia SQL (con distintos valores) muchas veces.
7.       GLOSARIO DE TERMINOS
 Sentencias: son los elementos básicos en los que se divide el código en un lenguaje de programación. Al fin y al cabo, un programa no es más que un conjunto de sentencias que se ejecutan para realizar una cierta tarea. 
Parámetros: es una variable utilizada para recibir valores de entrada en una rutina o subrutina. Dichos valores, que serán enviados desde la rutina invocante, son llamados argumentos.
Interfaz: es un conjunto de subrutinas, funciones y procedimientos (o métodos, en la programación orientada a objetos) que ofrece cierta biblioteca para ser utilizado por otro software como una capa de abstracción.
Sentencias compiladas: puede contener sentencias de control SQL y sentencias SQL. Las sentencias SQL compuestas (compiladas) se pueden utilizar para implementar la lógica de procedimiento a través de una secuencia de sentencias SQL con un ámbito local para variables, condiciones, cursores y manejadores.
DBMS: database management system  que permiten almacenar y posteriormente acceder a los datos de forma rápida y estructurada.

8.       BIBLIOGRAFÍA


LINK DE LAS DIAPOSITIVAS DEL TEMA

http://es.slideshare.net/MagalyPortocarreroLa/preparedstatement-69897191