Introducción
API JDBC en Java 7 (Paquetes principales)
Uso de JDBC
El paquete java.sql consiste en ejecutar sentencias SQL de tipo consulta, aunque también permite leer y escribir datos mediante operaciones de modificación realizando su conexión des de cualquier fuente de datos utilizando un formato tabular (en forma de tupla).
La URL del JDBC se construye mediante la plantilla siguiente:
jdbc : subprotocolo : subnombre
3.-El último paso consiste en ejecutar la sentencia SQL y gestionar la tupla obtenida como resultado de su ejecución parametrizando la información según se requiera.
Por otro lado el paquete javax.sql, proporciona una API en la capa del servidor para el acceso a la fuente de datos y procesado del lenguaje de programación Java. Incorpora los siguientes añadidos:
- La interfície de DataSource como una alternativa al DriverManager para establecer la conexión con una fuente de datos.
- Pooling de conexiones y sentencias de SQL.
- Transacciones distribuidas.
- Conjuntos de filas.
- Aplicaciones para utilizar directamente las API’s DataSource y RowSet, aunque las API’s del pooling de conexiones y de ls transacciones distribuidas se utilizan internamente por intermediarios.
Fig. 2. Cierre de la conexión |
- El cierre de Connection cierra automáticamente todos los recursos.
- El cierre del objeto ResultSet debe realizarse explícitamente siempre que no se utilice dado que si se deja automáticamente sólo se cerrará cuándo sea analizado por el recolector de basura. Es una buena práctica siempre cerrarlo explícitamente.
- Por último siempre cerrar cualquier recurso externo que sea capaz de mantener activa la conexión del SGBD.
try (Connection con = DriverManager.getConnection(url, username, password)); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(query); { // Using resources }catch(Exception ex) { }
Sql y JDBC
La API del JDBC:
- No restringe las sentencias que se pueden utilizar en una BBDD.
- No controla que las sentencias enviadas a la BBDD estén correctamente formuladas.
- Suministra tres clases y tres métodos respectivamente para el envío de sentencias SQL:
Fig. 3. Creacion de objetos SQL |
- Statement: Utiliza el método de createStatement y incluye los métodos de executeQuery (para consultas) y executeUpdate(para operaciones de modificación).
- PreparedStatement: Se utiliza para enviar consultas SQL que tengan uno o más parámetros como argumentos de entrada. Cuenta con métodos propios que nos ayudan a dar valor a estos parámetros. Se muestra el siguiente código fuente como ejemplo:
PreparedStatement ps = con.prepareStatement( "select * from OWNER where ID=? AND NAME=? AND CODE=?"); ps.setInt(1,id-employee); ps.setString(2,name); ps.setInt(3,code);
- CallableStatement: Se usan para ejecutar procedimientos almacenados SQL (Stored Procedures). Éstos son un grupo de sentencias SQL que son llamados mediante un nombre. Un objeto CallableStatement hereda de PreparedStatement los métodos para el manejo de parámetros y además añade métodos para el manejo de estos parámetros. Se muestra el siguiente código fuente como ejemplo:
String createProcedure = "create procedure SHOW_SUPPLIERS " + "as "+"select SUPPLIERS.SUP_NAME, COFFEES.COF_NAME " + "from SUPPLIERS, COFFEES " + "where SUPPLIERS.SUP_ID=COFFEES.SUP_ID " + "order by SUP_NAME"; CallableStatement cs = con.prepareCall("{call SHOW_SUPPLIERS}");
Toda acción que se realice sobre la BBDD de datos abrir/cerrar conexión, ejecutar una sentencia SQL, etc pueden lanzar una excepción del tipo SQLException que se deberá capturar o propagar.
Este error puede resultar crítico para la integridad de los datos de la BBDD: la clase SQLException hereda de Iterable lo que permite recorrer dicha cadena de fallos. Así es posible recorrer todos los objetos de tipo Throwable que haya en una excepción SQLException.
Transacción
Mecanismo para manejar grupos de operaciones como si fueran una acción realizada de forma única.
Cada transacción debe tener las propiedades ACID:
- Atomicidad (Atomicity). Una operación se hace o se deshace por completo.
- Consistencia (Consistency). Transformación de un estado consistente a otro estado consistente.
- Aislamiento (Isolation). Cada transacción se produce con independencia de otras transacciones que se produzcan al mismo tiempo.
- Permanencia (Durability). Propiedad que hace que las transacciones realizadas sean definitivas.
Con JDBC se ejecuta un COMMIT automático (autoCOMMIT) tras cada insert, update o delete (con excepción de si se trata de un procedimiento almacenado).
Para indicar que una sentencia SQL no se ejecuta de forma automática se utilizará el método setAutommit(boolean); de la interfaz Connection pasándole como parámetro el valor false.
De este modo se pueden agrupar varias sentencias SQL en una misma transacción siendo el programador el que gestiona el momento de realizar el COMMIT de la ejecución.
Api RowSet
Fig. 4. RowSet Api Description |
CachedRowSet
Permite obtener una conexión des de un DataSource, además de permitir la actualización y desplazamiento de datos sin necesidad de disponer de la conexión a BBDD abierta.
FilterRowSet
Deriva de RowSet y añade la posibilidad de aplicar criterios de filtros para hacer visible cierta porción de datos de un resultado global.
JdbcRowSet
Clase que engloba el funcionamiento básico de un ResultSet y añade capacidades de desplazamiento y actualización de datos.
JoinRowSet
Deriva de WebRoseSet y añade capacidades similares al JOIN de SQL pero sin necesidad de estar conectado a la fuente de datos.
WebRowSet
Deriva de CachedRowSet y añade funcionalidad para la lectura y escritura de documentos XML.
Las clases que componen la API son las siguientes:
BaseRowSet
Clase base abstracta que provee un objeto RowSet junto a su funcionalidad básica.
RowSetMetadaImpl
Clase que proporciona implementaciones para los métodos que establecen y recuperan información de los metadatos de las columnas del objecto RowSet.
Un objeto RowSetMetaDataImpl realiza un seguimiento del número de columnas del RowSet y mantiene un Array interno de los atributos de la columna para cada una de las columnas.
Un objeto RowSet crea internamente un objeto RowSetMetaDataImpl con el fin de establecer y recuperar información sobre sus columnas.
RowSetProvider
Se utiliza para crear un objeto RowSetFactory. A su vez, RowSetFactory se utiliza para crear instancias de implementaciones de RowSet (que deriva de ResultSet y por lo tanto contiene todas las capacidades de ResultSet pero añadiendo nuevas funcionalidades).