martes, 6 de diciembre de 2016

DESARROLLO DE SOFTWARE I

                                          
                                             PreparedStatement


                                           DESARROLLO DE SOFTWARE I



           1. CONTENIDO

     DEFINICIÓN:

Una PreparedStatement 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. La interfaz PreparedStatement hereda de Statement y difiere de esta en dos maneras.
Las instancias de PreparedStatement contienen una sentencia SQL que ya ha sido compilada. Esto es lo que hace que se le llame ‘preparada’.
La sentencia SQL contenida en un objeto PreparedStatement pueden tener uno o más parámetros IN. Un parámetro IN 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 IN. Debe suministrarse un valor para cada interrogante mediante el método apropiado set XXX antes de ejecutar la sentencia.
Como los objetos PreparedStatement están precompilados, su ejecución es más rápida que los objetos Statement. Consecuentemente, una sentencia SQL que se ejecute muchas veces a menudo se crea como PreparedStatement para incrementar su eficacia.
Siendo una subclase de Statement, PreparedStatement hereda toda la funcionalidad de 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 IN. También se modifican los tres métodos execute, execute Query 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. 
Son muy útiles cuando una sentencia SQL se ejecuta muchas veces cambiando sólo algunos valores.
·         Se utiliza para enviar sentencias SQL pre compiladas con uno o más parámetros.
·         Se crea un objeto PreparedStatement especificando la plantilla y los lugares donde irán los parámetros.
·    Los parámetros son especificados después utilizando los métodos setXXX(.) indicando el número de parámetro y el dato a insertar en la sentencia.
·   La sentencia SQL y los parámetros se envían a la base de datos cuando se llama al método: executeXXX()
  • Método 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. Desde el controlador JDBC 3.0 de Microsoft SQL Server, executeUpdate devolverán el número correcto de filas.

  • Lista de sobrecargas


Nombre
Descripción
executeUpdate (java.lang.String)
Ejecuta la instrucción SQL determinada, que puede ser una instrucción INSERT, UPDATE, DELETE o MERGE; o una instrucción SQL que no devuelve nada, como una instrucción DDL de SQL.
executeUpdate (java.lang.String, int)
Ejecuta la instrucción SQL especificada y señala al Controlador JDBC de Microsoft para SQL Server con la marca indicada sobre si las claves generadas automáticamente producidas por este objeto SQLServerStatement deben estar disponibles para su recuperación.
executeUpdate (java.lang.String, int[])
Ejecuta la instrucción SQL determinada e indica al controlador JDBC que las claves que se han generado automáticamente y están presentes en la matriz determinada deben estar disponibles para su recuperación.
executeUpdate (java.lang.String, java.lang.String[])
Ejecuta la instrucción SQL determinada e indica al controlador JDBC que las claves que se han generado automáticamente y están presentes en la matriz determinada deben estar disponibles para su recuperación.

El executeUpdate( ) método funciona igual que el execute( ) método, excepto que devuelve un valor entero que indica el número de filas afectadas por la instrucción SQL. El executeUpdate() método combina eficazmente el execute() y getUpdateCount( ) métodos en una sola llamada:

int RSLT = 0;
Declaración stmt = null;
tratar {
  stmt = conn.createStatement ();
  RSLT = stmt.executeUpdate ( "eliminar persona");
  . . .
}
  • Uso de CallableStatement

Un objeto CallableStatement provee de una forma estándar de llamar a procedimientos almacenados de la base de datos. Un procedimiento almacenado se encuentra en la base de datos. La llamada al procedimiento es lo que contiene el objeto CallableStatement. Esta llamada se escribe en una sintaxis de escape que puede tomar una de dos formas: un formato con un parámetro resultado y el otro sin él. Un parámetro resultado, un tipo de parámetro OUT, es el valor devuelto por el procedimiento almacenado. Ambos formatos pueden tener un número variable de parámetros de entrada (parámetros IN), de salida (parámetros OUT) o ambos (parámetros INOUT). Un interrogante sirve como ‘anclaje’ para cada parámetro.
La sintaxis para invocar un procedimiento almacenado en JDBC se muestra a continuación: Notar que los corchetes indican que lo que se encuenta contenido en ellos es opcional, no ofroma parte de la sintaxis.
  {call procedure_name[(?, ?, ...)]}
La sintaxis para un procedimiento que devuelve un resultado es:
  {? = call procedure_name[(?, ?, ...)]}
La sintaxis para un procedimiento almacenado sin parámetros se parece a algo como:
  {call procedure_name}
CallableStatement hereda los métodos de Statement, los cuales tratan sentencias SQL en general, y también hereda los métodos de PreparedStatement, que tratan los parámetros IN. Todos los métodos definidos para CallableStatement tratan los parámetros OUT o los aspectos de salida de los parámetros INOUT: registro de los tipos JDBC (tipos genéricos SQL) de los parámetros OUT, recuperación de valores desde ellos o chequear si el valor devuelto es un JDBC NULL.
  • Crear objetos CallableStatement

Los objetos CallableStatement se crean con el método prepareCall de Connection. El siguiente ejemplo crea una instancia de CallableStatement que contiene una llamada al procedimiento almacenado getTestData, con dos argumentos y no devuelve resultados.
CallableStatement cstmt = con.prepareCall(
"{call getTestData(?, ?)}");
donde los encajes ‘?’ son parámetros IN, OUT ó INOUT dependiendo del procedimiento getTestData.
  • Ejemplos

Ejemplo N°01
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();

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();

Ejemplo N°02
Este Es Un ejemplo de utilización del Método executeUpdate del Objeto Declaración.
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.
        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("No se ha podido registrar el controlador.");
            System.out.println(e.getMessage());
            System.exit(1);
        }
       Connection c = null;
        Statement s = null;
        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.
            c = DriverManager.getConnection(URL, properties);
 
            // Crear un objeto Statement.
            s = c.createStatement();
            // Suprimir la tabla de prueba, si existe. Nota: en este 
            // ejemplo se presupone que la colección MYLIBRARY
            // existe en el sistema.
            try {
                s.executeUpdate("DROP TABLE MYLIBRARY.MYTABLE");
            } catch (SQLException e) {
                // Continuar simplemente... es probable que la tabla no exista.  
            }
            // Ejecutar una sentencia SQL que crea una tabla en la base de datos.
            s.executeUpdate("CREATE TABLE MYLIBRARY.MYTABLE (NAME VARCHAR(20), ID INTEGER)");
 
            // Ejecutar algunas sentencias SQL que insertan registros en la tabla.
            s.executeUpdate("INSERT INTO MYLIBRARY.MYTABLE (NAME, ID) VALUES ('RICH', 123)");
            s.executeUpdate("INSERT INTO MYLIBRARY.MYTABLE (NAME, ID) VALUES ('FRED', 456)");
            s.executeUpdate("INSERT INTO MYLIBRARY.MYTABLE (NAME, ID) VALUES ('MARK', 789)");
 
            // Ejecutar una consulta SQL en la tabla.
            ResultSet rs = s.executeQuery("SELECT * FROM MYLIBRARY.MYTABLE");
 
            // 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 {
   // Cerrar 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.");
            }
             }
 
            try {
                if (c != null) {
                    c.close();
                }
            } catch (SQLException e) {
                System.out.println("El borrado no ha podido cerrar Connection.");
            }
        }
    }
} 
Ejemplo N° 03
A continuación Los muestro un simple ejemplo completo para ver un poquito lo que hemos explicado anteriormente acerca de CallableStatement. 
Package formularios
import java.sql.CallableStatement;  
import java.sql.Connection;  
import java.sql.ResultSet;  
import java.sql.SQLException;  
import java.sql.Types;  
  
public class SampleStoredProcedures {  
  
    public static void main(String[] args) throws SQLException{  
  
        Connection conn = null;  
        try {  
            // Creamos la conexion  
            conn=ConnectionMySQL.conectar("localhost", "user", "password", "****");  
            conn.setAutoCommit(false);  
              
             CallableStatement cStmt = conn.prepareCall("{call demoSp(?, ?)}");    
             cStmt.setString(1, "abcdefg");    
             cStmt.setInt(2, 0);  
             cStmt.registerOutParameter("inOutParam", Types.INTEGER);    
              
             cStmt.execute();    
             final ResultSet rs = cStmt.getResultSet();  
              
             while (rs.next()) {  
                 System.out.println("Cadena de caracteres pasada como parametro de entrada="+rs.getString("inputParam"));  
             }    
              
             int outputValue = cStmt.getInt("inOutParam");  
             System.out.println("Parametro de salida incrementado="+outputValue);  
        }catch (Exception e) {  
            conn.rollback();  
            e.printStackTrace();  
        }finally{  
            conn.close();  
        }  
    }  
}

2. RESUMEN
PreparedStatement tiene un grupo de métodos que fijan los valores de los parámetros IN, los cuales son enviados a la base de datos cuando se procesa la sentencia SQL.
Las Instancias de PreparedStatement extienden, es decir, heredan de Statement y por tanto heredan los métodos de Statement. Un objeto PreparedStatement es potencialmente más eficiente que un objeto Statement porque este ha sido precompilado y almacenado para su uso futuro.
El método 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.
Mientras CallableStatement soporta llamar a cualquiera de los métodos de ejecución de Statement ( executeUpdate(), executeQuery() o execute() ), el método más flexible es execute(), ya que no necesita saber de antemano si el procedimiento almacenado retorna un conjunto de resultados.
3. SUMMARY
PreparedStatement has a set of methods that set the IN parameter values, which are sent to the database when the SQL statement is processed.
The PreparedStatement Instances extend, that is, inherit from Statement and therefore inherit Statement methods. A PreparedStatement object is potentially more efficient than a Statement object because it has been precompiled and stored for future use.
The executeUpdate () method executes the given SQL statement, which can be an INSERT, UPDATE, or DELETE statement; Or an SQL statement that does not return anything, such as a SQL DDL statement.
While CallableStatement supports calling any of the statement execution methods (executeUpdate (), executeQuery () or execute ()), the most flexible method is execute (), since you do not need to know in advance whether the stored procedure returns a set Of results.
 4. RECOMENDACIONES:
·         Para poder usar una Prepared Statement real desde java, es necesario que tanto la base   de datos como el driver java que usemos soporten las PreparedStatement..
·    MySQL sí soporta los Preparedstatement y los driver modernos de MySQL para java también lo soportan. Sin embargo, debemos habilitarlos en el momento de establecer la conexión.
· Por razones de rendimiento, intentado minimizar llamadas innecesarias a Connection.prepareCall() rehusando instancias de CallableStatement.
 5. CONCLUSIONES

  • Connection.prepareCall() es un método costoso, debido a la petición de metadatos que hace el driver para suportar los parámetros de salida. 
  • Como hemos visto la interfaz CallableStatements nos permite ejecutar procedimientos almacenados e interactuar con el resultado de una manera rápida y sencilla posicionandose como una buena opción a la hora de trabajar con procedimientos almacenados. Espero que les sirva de utilidad.
  •  El método executeUpdate únicamente permite realizar sentencias de actualización de la BD: creación de tablas (CREATE), inserción (INSERT), actualización (UPDATE) y borrado de datos (DELETE).

    6. APRECIACIÓN DEL EQUIPO
Como ya hemos mencionado nuestro marco teórico y hemos apreciado el tema principal como es PreparedStatement que 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 TÉRMINOS

Compilador: Un compilador es un programa informático que traduce un programa escrito en un lenguaje de programación a otro lenguaje diferente. Usualmente el segundo lenguaje es lenguaje de máquina, pero también puede ser un código intermedio (bytecode), o simplemente texto. Este proceso de traducción se conoce como compilación.
Parámetros: Son los argumentos que aparecen en la llamada a un método. Contienen los valores que se le pasan al método.
Subclase: Los métodos y variables que posee un objeto definen la clase a la cual pertenece
Plantilla: Una plantilla agiliza el trabajo de reproducción o de muchas copias idénticas o casi idénticas (que no tiene que ser tan elaborado, sofisticado o personal).
Controlador JDBC: es un componente de software que permite a las aplicaciones escritas en Java interactuar con una base de datos.

 LINKOGRAFÍA