jdbc son las siglas de java database connectivity

39
JDBC son las siglas de Java DataBase Connectivity, o lo que es lo mismo: Conectividad de Bases de Datos Java. Estas siglas son concedidas a una API que está especialmente dedicada a la gestión de bases de datos, permitiendo ejecutar sentencias en SQL (Structured Query Language o Lenguaje Estructurado de Consultas ), con las que se pueden crear tablas e índices, modificar datos, eliminar información, añadir, consultar, etc. Bases de datos Las bases de datos son conjuntos de tablas, las cuales son entidades que almacenan la información de manera estructurada, de forma similar a una rejilla de celdas. Cada fila representa a un registro o colección de datos referente a una entidad, individuo, artículo, etc. Cada columna representa un campo o tipo de información, como puede ser un nombre, una dirección, un importe, una fecha, etc. Las tablas pueden tener asociados índices, los cuales permiten una optimización de búsqueda a través de uno o varios campos determinados de la tabla. Las bases de datos son, sin lugar a dudas, el motor principal para la gestión de la información, y por ello son utilizadas por empresas, organizaciones, particulares, etc. En el mercado existen multitud de empresas que se dedican a definir un producto de gestión de bases de datos. Pero las más potentes y las más utilizadas actualmente son: Oracle, SQL Server, Informix, Sybase, DB/2, Access, Paradox, FoxPro, dBASE, etc. Otro dato fundamental a tener en cuenta es que las bases de datos pueden ser gestionadas a través de la red. Esto significa que la base de datos y toda su información pueden residir en un ordenador llamado servidor, que es quien provee y gestiona la bases de datos en relación a una serie de permisos de acceso. Los ordenadores conectados por red a

Upload: henry-garcia-ospina

Post on 05-Jul-2015

239 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: JDBC Son Las Siglas de Java DataBase Connectivity

JDBC son las siglas de Java DataBase Connectivity, o lo que es lo mismo: Conectividad de Bases de Datos Java. Estas siglas son concedidas a una API que está especialmente dedicada a la gestión de bases de datos, permitiendo ejecutar sentencias en SQL (Structured Query Language o Lenguaje Estructurado de Consultas), con las que se pueden crear tablas e índices, modificar datos, eliminar información, añadir, consultar, etc.

Bases de datos

Las bases de datos son conjuntos de tablas, las cuales son entidades que almacenan la información de manera estructurada, de forma similar a una rejilla de celdas. Cada fila representa a un registro o colección de datos referente a una entidad, individuo, artículo, etc. Cada columna representa un campo o tipo de información, como puede ser un nombre, una dirección, un importe, una fecha, etc.

Las tablas pueden tener asociados índices, los cuales permiten una optimización de búsqueda a través de uno o varios campos determinados de la tabla.

Las bases de datos son, sin lugar a dudas, el motor principal para la gestión de la información, y por ello son utilizadas por empresas, organizaciones, particulares, etc.

En el mercado existen multitud de empresas que se dedican a definir un producto de gestión de bases de datos. Pero las más potentes y las más utilizadas actualmente son: Oracle, SQL Server, Informix, Sybase, DB/2, Access, Paradox, FoxPro, dBASE, etc.

Otro dato fundamental a tener en cuenta es que las bases de datos pueden ser gestionadas a través de la red. Esto significa que la base de datos y toda su información pueden residir en un ordenador llamado servidor, que es quien provee y gestiona la bases de datos en relación a una serie de permisos de acceso. Los ordenadores conectados por red a dicho servidor se denominan clientes, y deben poseer los permisos y las condiciones necesarias para poder acceder a la información.

ODBC

Como resulta obvio deducir, cada sistema de base de datos implementa sus propias características, como pueden ser el modo de acceder a los datos, los tipos de datos soportados, los entornos, las configuraciones, etc. A pesar de que la mayoría de los productos indicados anteriormente utilizan el lenguaje estándar SQL, cada uno trata de manera diferente (para el rendimiento óptimo) cada sentencia y cada uno difiere un poco del estándar y añaden su propia funcionalidad.

Page 2: JDBC Son Las Siglas de Java DataBase Connectivity

Para poder unificar toda esta diversidad, Microsoft planteó una especificación llamada ODBC (Object DataBase Connectivity), mediante la cual el fabricante de una base de datos determinada podría generar un driver siguiendo esta especificación. Entonces, realizar una aplicación que acceda a la base de datos es ya algo tangible, pues el driver ODBC resuelve muchos escollos de incompatibilidad. Una sentencia en SQL puede ser ejecutada – teóricamente – para cualquier sistema de base de datos y los tipos de datos retornados y facilitados pueden ser aceptados casi sin problemas. Primero está ODBC, que tras comprobar que las sentencias SQL respetan la especificación, remiten la solicitud de ejecución a la base de datos remota.

Pero no nos engañemos, ODBC ha sido un gran avance, pero no la solución total a la incompatibilidad. Una sentencia SQL generada en – por ejemplo – Oracle puede no ser ejecutada correctamente en SQL Server o en Informix. Hay algunas sutilezas propias de un determinado gestor de bases de datos que hay que refinar, y por ello, una aplicación que pueda atacar a distintas bases de datos debe tener en cuenta la sintaxis y el formato de los datos para cada gestor. No obstante, existe un mínimo estándar que se suele respetar, y hoy en día ODBC se ha convertido en una interfaz estándar e, indiscutiblemente, la más utilizada en Windows.

JDBC

Javasoft desarrolló un conjunto de clases que permiten gestionar bases de datos, independientemente de la base de datos utilizada y de la plataforma en que se ejecute la aplicación o applet en Java. Este conjunto de clases conforman un API (Applications Programming Interface o Interface de Programación de Aplicaciones), el cual se denomina JDBC (Java DataBase Connectivity o Conectividad de Bases de Datos de Java).

Gran parte del diseño de JDBC estuvo influenciado por ODBC, en gran parte debido a la amplia aceptación de ODBC y a la oportunidad que tenía para popularizarse más. Del mismo modo que ODBC, JDBC precisa de los drivers o controladores apropiados para cada sistema de base de datos.

JDBC es un API, un conjunto de clases e interfaces estándar que permite un fácil y rápido acceso a las bases de datos, independientemente del sistema de bases utilizado. Este conjunto de clases e interfaces son gestionadas por un controlador, el cual se encarga de traducir las llamadas requeridas por la base de datos. Los controladores de cada sistema de base de datos deben ser compatibles con la especificación estándar ANSI SQL-2 Entry Level.

A diferencia de ODBC, la conectividad JDBC está completamente escrita en código Java, evitando así el uso de punteros y los conflictos que éstos provocan.

Controladores JDBC

Page 3: JDBC Son Las Siglas de Java DataBase Connectivity

JDBC puede utilizar cuatro tipos de controladores.

Controlador JDBC-ODBC

El controlador JDBC-ODBC permite reutilizar lo ya existente, estableciendo un puente entre JDBC y ODBC, convirtiendo las llamadas y los resultados entre ambos gestores. Este tipo de controlador es de los más utilizados por su facilidad de acceso y su disponibilidad, ya que se puede prescindir del controlador específico para JDBC. Asimismo, el medio ODBC es, hoy en día, el más utilizado y cada fabricante de sistemas de bases de datos ofrece su driver correspondiente para la especificación de Microsoft.

Por el contrario, el problema que se plantea es el de siempre: debe existir una copia del driver ODBC en cada máquina local para poder acceder a la base de datos, por lo que la seguridad peligra. Asimismo este tipo de controlador implica también que las aplicaciones correrán exclusivamente en la plataforma Windows, renegando del resto de plataformas. Por si esto fuese poco, si el gestor JDBC debe traducir las llamadas y los resultados a ODBC, y ODBC, a su vez, a código nativo para comunicarse con el sistema de base de datos, el tiempo invertido para realizar el acceso a los datos puede ser excesivo.

Controlador Java nativo

El controlador de Java nativo es un driver escrito íntegramente en Java, y permite comunicarse directamente con las librerías nativas del fabricante del sistema de base de datos.

Page 4: JDBC Son Las Siglas de Java DataBase Connectivity

La ventaja de este tipo de controlador es que no tiene que pasar por ODBC, con lo que se gana rapidez y en eficiencia. Por el contrario, se requiere de una parte en binario, que son las bibliotecas del fabricante, en cada máquina cliente.

Controlador Java – protocolo nativo

Este tipo de controlador utiliza un driver completamente realizado en Java, el cual se comunica directamente con el servidor de bases de datos, a través del protocolo nativo de red.

Este tipo de controlador posee grandes ventajas:

* No se necesita bibliotecas intermedias. * El driver convierte todas las consultas en peticiones directas contra el servidor a través de la red. * Es totalmente independiente de la máquina en la que se ejecute. * Es una solución íntegra en Java.

Por el contrario, el principal problema es que cada sistema de base de datos utiliza un protocolo de red propio, lo que obliga a que el cliente esté irremediablemente vinculado a un sistema de base de datos determinado.

Controlador Java – protocolo independiente

Este tipo de controlador requiere que las bibliotecas del fabricante estén en el lado del servidor, que actuarán como intermediario entre las peticiones del driver JDBC del cliente y el servidor de la base de datos, traduciendo éstas a peticiones nativas.

Page 5: JDBC Son Las Siglas de Java DataBase Connectivity

La principal ventaja de este tipo de controlador es que, además de utilizar un driver 100% Java, es totalmente independiente con respecto al sistema de base de datos utilizado y del protocolo de red (se utiliza un protocolo de red genérico). Si en el futuro se decide cambiar el sistema de base de datos, únicamente hay que cambiar el intermediario.

La mejor forma de ilustrar la gestión de bases de datos con Java es mediante un ejemplo. Por ello, este capítulo estará dedicado a un ejemplo bastante simple, en el que una aplicación en Java establecerá una conexión con una base de datos a través del puente JDBC-ODBC. Una vez establecida la conexión generará una consulta a través de SQL, relacionando varias tablas y obteniendo un conjunto de registros, los cuales recorrerá y visualizará.

La aplicación, por fines didácticos, no contendrá ningún componente visual, y se dedicará más directamente con el tratamiento de la base de datos.

Aunque el ejemplo utilice ODBC (e, irremediablemente, sea exclusivo para los usuarios de Windows), es importante no pasar por alto este capítulo, pues en él se adquieren conocimientos importantes para el resto de controladores JDBC.

En capítulos posteriores se detallará cada una las partes que intervienen en la gestión de bases de datos en Java.

Diseño de la base de datos

Para este ejemplo se ha utilizado una base de datos Microsoft Access 2000, aunque este aspecto es irrelevante, puesto que todo el trabajo lo hace ODBC y no importa el gestor de bases de datos utilizado. Este dato es más que anecdótico, con el fin de que el lector pueda reproducir el ejemplo.

Se ha construido un hipotético caso de gestión de un almacén. Para ello se han definido cuatro tablas: Clientes, Productos, Pedidos y Detalle_Pedidos. Aunque en un caso real los criterios utilizados cambian, los campos pueden ampliarse y el número de tablas y de relaciones también, para ilustrar este ejemplo se ha escogido lo más indispensable para ilustrar un ejemplo.

Page 6: JDBC Son Las Siglas de Java DataBase Connectivity

En primer lugar, se ha definido la tabla Clientes, con el fin de recoger toda la información inherente a los clientes de la empresa. Estos clientes harán pedidos, que serán gestionados con los productos que hay en el almacén. El diseño, en su formato básico, es el siguiente:

Campo Tipo Longitud Cod_Cliente Numérico Entero Largo Nombre Texto 50 Direccion Texto 50 Poblacion Texto 30 Provincia Texto 25 Telefono Texto 20

El índice recae sobre el campo Cod_Cliente, el cual asigna un identificador único al cliente (puede haber varios clientes con el mismo nombre y/o con los mismos datos, pero cada uno contendrá un ID diferente, y por tanto será identificado y tratado como cliente diferente). Por tanto, este campo no podrá contener valores nulos, será obligatorio rellenarlo y además no podrá estar repetido. Se dice entonces que es una clave principal.

A continuación se define la tabla Productos, la cual contendrá la información referente a cada uno de los productos que vende la empresa y que posee en el almacén, y permite la gestión del stock. Su diseño se ilustra a continuación:

Campo Tipo Longitud Cod_Producto Numérico Entero Largo Descripcion Texto 50 PVC Numérico Double PVP Numérico Double Unidades Numérico Entero Largo Reservas Numérico Entero Largo

Los campos PVC y PVP recogen la información sobre el coste del producto. El campo PVC (Precio Venta Cesión) almacena el precio de coste del producto, mientras que el campo PVP (Precio Venta Público) almacena el precio de venta. La diferencia entre PVP y PVC representa el margen de beneficio de la venta.

De cada producto se registran las unidades reales existentes en el almacén, mediante al campo Unidades. Pero hay que tener en cuenta que el que exista un número determinado de productos no significa que estén todos disponibles, pues pueden existir pedidos sin despachar. En el campo Reservas se registra las unidades que se reservan tras un pedido. La diferencia entre las unidades reales y las unidades reservadas representa las unidades disponibles realmente.

El índice suministrado recae sobre el campo Cod_Producto, el cual posee el identificador único del producto y, por consiguiente, será una clave. Por tanto, al igual que en la tabla Clientes, este campo no admitirá valores nulos, será obligatorio rellenarlo y no permitirá duplicidad en sus valores.

Page 7: JDBC Son Las Siglas de Java DataBase Connectivity

El siguiente paso es definir la tabla Pedidos, la cual registrará cada uno de los pedidos realizados por el cliente. Su diseño es el siguiente:

Campo Tipo Longitud Num_Pedido Numérico Entero Largo Cod_Cliente Numérico Entero Largo Fecha Fecha/Hora

En cada pedido hay un número de pedido, el cual es asignado para un determinado cliente en una determinada fecha.

Esta tabla poseerá una clave principal (Num_Pedido) y una clave secundaria (Cod_Cliente). La clave principal es única y no podrá existir dos pedidos con el mismo número de pedido. Sin embargo, sí pueden aparecer varios clientes, ya que un cliente puede realizar múltiples pedidos.

Por último, se define la tabla Detalle_Pedidos, la cual se encarga de registrar todos los productos pedidos por el cliente. Su diseño es el que sigue:

Campo Tipo Longitud Num_Pedido Numérico Entero Largo Cod_Producto Numérico Entero Largo Unidades Numérico Entero Largo

Cada registro en esta tabla corresponde a cada producto pedido por el cliente. Por tanto, puede haber múltiples registros para un solo pedido. Por ello, el índice recae sobre los campos Num_Pedido y Cod_Producto, sin clave principal. En ambos campos no se permiten valores nulos y es obligatorio rellenar dichos campos. Pero sus valores pueden estar duplicados.

La relación de todas las tablas quedaría de la siguiente manera:

Page 8: JDBC Son Las Siglas de Java DataBase Connectivity

Datos utilizados

Los datos que se han introducido para ilustrar el ejemplo son los siguientes:

TABLA CLIENTES

Cod_Cliente Nombre Direccion Poblacion Provincia Telefono 1 GERFOSA C/ Almagro, 3 Móstoles Madrid 916474558 2 JUKALI C/ Donoso, 21 Getafe Madrid 916833520 3 SITNA C/ Castillo, 34 Alcorcón Madrid 916124748

TABLA PRODUCTOS

Cod_Producto Descripcion PVC PVP Unidades Reservas 1 Monitor 14’’ 15800 25000 40 12 2 Teclado 1500 3500 25 2 3 Raton 500 995 500 247

TABLA PEDIDOS

Num_Pedido Cod_Cliente Fecha 1 3 14/06/2000 2 2 14/06/2000 3 2 15/06/2000 4 3 16/06/2000 5 1 16/06/2000

TABLA DETALLE_PEDIDOS

Num_Pedido Cod_Producto Unidades 1 2 5 1 3 10 2 1 2 3 1 3 3 3 25 4 3 5 5 1 1 5 2 14 5 3 14

Configuración de ODBC

Para configurar ODBC es necesario acceder al la barra de inicio de Windows, seleccionar la opción Configuración y la subopción Panel de Control (también se puede

Page 9: JDBC Son Las Siglas de Java DataBase Connectivity

acceder mediante el icono Mi PC del escritorio). En la ventana que aparece, se hace doble click sobre el icono Fuentes de Datos ODBC (32 bits), con lo que aparecerá la siguiente ventana:

En esta ventana se pueden apreciar que aparecen los controladores de orígenes de datos que tenga instalados la máquina local. Es necesario, pues, que exista el controlador apropiado para el gestor de base de datos a utilizar en la aplicación. Si la base de datos está gestionada – por ejemplo - en Oracle 8.0., es necesario haber instalado previamente el driver de Oracle 8.0. en la máquina local.

El driver correspondiente debería aparecer en la primera solapa de esta ventana (DSN de usuario), pero si no es así, se puede comprobar en la solapa Controladores.

Para crear un origen de datos ODBC, hay que seleccionar la solapa DSN de Sistema, con lo que se mostrará una lista de orígenes de datos existentes (si es la primera vez, la lista aparecerá vacía).

Page 10: JDBC Son Las Siglas de Java DataBase Connectivity

Ahora se hace click sobre el botón Agregar..., en donde aparecerá una nueva ventana en donde se selecciona el driver de base de datos apropiado de entre todos los disponibles en la máquina.

En nuestro caso se seleccionar el driver de Microsoft Access Driver (*.mdb) y se hace click sobre el botón Finalizar.

En este momento, dependiendo del driver seleccionado, se abre un asistente con el que se establecen los parámetros de localización de la base de datos a utilizar, el

Page 11: JDBC Son Las Siglas de Java DataBase Connectivity

nombre de usuario, la contraseña, etc. En el caso de Microsoft Access, la ventana de configuración es la siguiente:

El campo Nombre del origen de datos representa el nombre identificativo en ODBC, con el cual referirnos a la conexión.

Para seleccionar la base de datos a utilizar, se hace click sobre el botón Seleccionar..., en el que se desplegará una caja de diálogo de archivos, en donde navegaremos a la máquina donde se alberga la base de datos (en nuestro caso la máquina local misma), la unidad de disco, el directorio y el nombre del archivo (Almacen.mdb).

Si el acceso a esta base de datos se desea – o se requiere - realizar mediante un nombre de usuario y una contraseña, se debe especificar estos datos haciendo click sobre el botón Avanzado..., con lo que aparecerá una ventana como la siguiente:

Page 12: JDBC Son Las Siglas de Java DataBase Connectivity

Una vez configurado el origen de los datos ODBC, se hace click sobre el botón Aceptar, donde volverá a la ventana de Administrador de orígenes de datos ODBC, con el nuevo origen de datos en la lista. Desde esta misma ventana puede cambiarse la configuración de un determinado origen de datos.

Fases del acceso a bases de datos

Para acceder a una base de datos en Java se puede dividir el proceso en dos niveles básicos: nivel de controlador y nivel de aplicación.

El nivel de controlador comprende la carga de los drivers necesarios para poder acceder a la base de datos.

El nivel de aplicación implica la creación de conexión a la base de datos, la creación de una sentencia de SQL que permita acceder a dicha base de datos y la ejecución de dicha sentencia, la cual puede o no retornar datos (resultset o resultado).

El nivel de controlador está gestionado por la clase DriverManager, que es la que se encarga de cargar los drivers JDBC. La interface Driver es la encargada de implementar el driver o controlador de la base de datos.

El nivel de aplicación está gestionado por diversas interfaces que se detallan a continuación.

La interfaz Connection es la encargada de establecer la conexión con la base de datos, y hace posible ejecutar sentencias SQL y procedimientos almacenados.

Page 13: JDBC Son Las Siglas de Java DataBase Connectivity

La interfaz Statement se encarga de ejecutar una sentencia SQL estática y de obtener los posibles registros resultantes.

La interfaz PreparedStatement es derivada de la interfaz Statement, y representa a una sentencia SQL precompilada o preparada. Este tipo de sentencias SQL, cuando se refieren a valores de campos, lo hacen mediante el signo interrogación, el cual será sustituido por un valor obtenido, de manera dinámica, mediante una variable u objeto.

La interfaz CallableStatement desciende, a su vez, de la interfaz PreparedStatement, y se utiliza para ejecutar procedimientos almacenados.

El siguiente esquema ilustra estos dos niveles básicos:

Las fases de acceso a bases de datos se pueden representar en cinco:

1. Cargar driver o controlador JDBC adecuado. 2. Crear la conexión a la base de datos. 3. Crear la sentencia JDBC. 4. Ejecutar la sentencia JDBC. 5. Acceso a los datos retornados (si los hay).

El siguiente esquema ilustra estas cinco fases:

Page 14: JDBC Son Las Siglas de Java DataBase Connectivity

Para el ejemplo propuesto, se desea acceder un resumen de todos los datos almacenados en el almacen. Para ello, se realiza una consulta, la cual dé la información del número de pedido, la fecha del mismo, el cliente que cursó el pedido, las unidades, producto, el precio de venta de cada unidad, y el precio total. Esto se consigue con la siguiente sentencia SQL:

SELECT Pedidos.Num_Pedido as NumPedido, Pedidos.Fecha as FechaPedido, Clientes.Nombre as NombreCliente, Detalle_Pedidos.Unidades as Cantidad, Productos.Descripcion as DescProducto, Productos.PVP as Precio, (Cantidad * Precio) as Total FROM Pedidos, Clientes, Detalle_Pedidos, Productos WHERE Pedidos.Cod_Cliente = Clientes.Cod_Cliente and Detalle_Pedidos.Cod_Producto = Productos.Cod_Producto and Detalle_Pedidos.Num_Pedido = Pedidos.Num_Pedido ORDER BY Pedidos.Num_Pedido

Page 15: JDBC Son Las Siglas de Java DataBase Connectivity

Con todos estos conceptos y con las ideas claras del propósito, se puede empezar a esbozar cada una de las fases necesarias para el acceso a la base de datos.

Cargar controlador JDBC

Para cargar de forma explíctita un driver o controlador JDBC determinado, se utiliza el método forName de la clase principal Class. Este método retorna un tipo Class, que representa una clase de objeto. Esta clase de objeto es el driver o controlador utilizado para acceder a la base de datos.

La clase DriverManager permite cargar drivers, pero intentará siempre cargar todos los drivers apuntados en la propiedad jdbc.drivers. Por ello, es recomendable utilizar el método forName para cargar un solo driver de manera explícita.

En nuestro caso, se desea acceder a la base de datos mediante ODBC, por lo que el controlador utilizado es el puente JDBC-ODBC, y se realiza de la siguiente manera:

// Cargar el driver JDBC-ODBC try { Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver"); } catch (Exception e1) { System.out.println ("No se puede cargar el driver JDBC-ODBC"); ... // Tratamiento de la excepcion }

Crear la conexión a la base de datos

Una vez cargado el driver correspondiente, el siguiente paso es crear la conexión a la base de datos. Para ello, es necesario utilizar la interfaz Connection, la cual representa una conexión o sesión de base de datos.

Para establecer una conexión, lo primero es declarar un objeto perteneciente a esta interfaz, tal y como demuestra la siguiente sentencia:

Connection conConexion;

La clase DriverManager es la encargada de gestionar los drivers o controladores de las bases de datos, por lo que también permite crear la conexión con la base de datos y retornar un objeto de tipo Connection con dicha conexión, y asignarlo al objeto definido anteriormente. En las siguientes líneas se demuestra cómo hacerlo:

// Crear la conexion con la base de datos try

Page 16: JDBC Son Las Siglas de Java DataBase Connectivity

{ conConexion = DriverManager.getConnection ("jdbc:odbc:Almacen", "rafinguer", "rafinguer"); ... } catch (Exception e2) { ... // Tratamiento de la excepcion }

En esta ocasión, el método getConnection posee tres parámetros.

El primer parámetro especifica la URL de la base de datos, dispuesta en esta sintaxis:

jdbc:odbc:nombre origen de datos

El segundo parámetro especifica el nombre de usuario para acceder a la base de datos.

El tercer parámetro especifica el password o contraseña de acceso.

Crear la sentencia JDBC

Una vez creada con éxito la conexión con la base de datos, el siguiente paso es crear una sentencia con la que la aplicación podrá enviar peticiones a la base de datos, tales como crear tablas, consultar datos, actualizar o modificar, borrar, etc.

Para nuestro ejemplo, se crea un objeto de tipo Statement:

Statement staSentencia;

A continuación se invoca al método createStatement del objeto Connection que contiene la conexión con la base de datos:

staSentencia = conConexion.createStatement ( );

Como se puede apreciar, el anidamiento de procesos pasan de un objeto a otro. Así, el objeto DriverManager crea la conexión delegándola en un objeto de tipo Connection, y este objeto, a su vez, crea una sentencia que delega en un objeto de tipo Statement. Todo esto tiene su sentido: una conexión debe saber qué controlador debe utilizar para acceder a una determinada base de datos, y una sentencia debe saber a qué base de datos debe de atacar, y esta información la contiene el objeto Connection.

Ejecutar la sentencia JDBC

Page 17: JDBC Son Las Siglas de Java DataBase Connectivity

Una vez creada la sentencia, se ejecuta dicha sentencia. Para ello, se proporciona, normalmente, una cadena de texto con una sentencia en lenguaje SQL. Dependiendo de la sentencia SQL se utiliza un determinado método.

Para nuestro ejemplo, que es una consulta, se utiliza el método executeQuery, el cual ejecuta una sentencia que retorna un conjunto de registros, llamado resultset o resultado. Este resultado es recogido mediante un objeto de tipo Resultset.

strSQL = "select Pedidos.Num_Pedido as NumPedido, "; strSQL = strSQL + "Pedidos.Fecha as FechaPedido, "; strSQL = strSQL + "Clientes.Nombre as NombreCliente, "; strSQL = strSQL + "Detalle_Pedidos.Unidades as Cantidad, "; strSQL = strSQL + "Productos.Descripcion as DescProducto, "; strSQL = strSQL + "Productos.PVP as Precio, "; strSQL = strSQL + "(Cantidad * Precio) as Total "; strSQL = strSQL + "from Pedidos, Clientes, "; strSQL = strSQL + "Detalle_Pedidos, Productos where "; strSQL = strSQL + "Pedidos.Cod_Cliente = Clientes.Cod_Cliente and "; strSQL = strSQL + "Detalle_Pedidos.Cod_Producto = Productos.Cod_Producto and "; strSQL = strSQL + "Detalle_Pedidos.Num_Pedido = Pedidos.Num_Pedido "; strSQL = strSQL + "order by Pedidos.Num_Pedido";

// Ejecucion de la sentencia y generacion del resultado try { resResultado = staSentencia.executeQuery (strSQL); ... // Tratamiento del resultado de la sentencia } catch (Exception e3) { ... // Tratamiento de la excepcion }

Acceso a los datos retornados

En nuestro ejemplo, la sentencia SQL es una SELECT, la cual selecciona registros de una o varias tablas, retornando registros o filas de datos. Estos registros deben ser capturados por un objeto de tipo Resultset (resultado), el cual se declara previamente:

ResultSet resResultado;

Como se pudo apreciar en la fase anterior, cuando se ejecuta la sentencia JDBC a través del método executeQuery, éste retorna un objeto de tipo Resultset, el cual se asigna al objeto Resultset declarado:

resResultado = staSentencia.executeQuery (strSQL);

Page 18: JDBC Son Las Siglas de Java DataBase Connectivity

Este objeto contiene todas los registros retornados por la sentencia. Para poder acceder a cada registro y extraer la información, la interfaz Resultset provee métodos para navegar a través de los registros o para capturar los valores de cada campo en el formato adecuado.

No es propósito de este capítulo abarcar todas estas características, pues en capítulos posteriores se tratará con más detalle.

El propósito de este ejemplo es acceder a todos los registros retornados y visualizarlos en la consola, uno a uno, desde el primero hasta el último. Para ello, se ha utilizado el método next, el cual accede al siguiente registro en el Resultset, y retorna el valor true si aún no ha llegado al final del Resultset (si todavía hay registros). Las siguientes líneas de código ilustran su uso:

// Recorrer el resultado while (resResultado.next ( )) { NumPedido = resResultado.getLong ("NumPedido"); Fecha = resResultado.getDate ("FechaPedido"); Nombre = resResultado.getString ("NombreCliente"); Unidades = resResultado.getLong ("Cantidad"); Descripcion = resResultado.getString ("DescProducto"); PVP = resResultado.getDouble ("Precio"); Total = resResultado.getDouble ("Total");

System.out.println ("Num_Pedido : " + NumPedido); System.out.println ("Fecha : " + Fecha); System.out.println ("Cliente : " + Nombre); System.out.println ("Unidades : " + Unidades); System.out.println ("Descripcion: " + Descripcion); System.out.println ("P.V.P. : " + PVP); System.out.println ("Total : " + Total); System.out.println (""); // Linea en blanco (separacion) }

El ejemplo al completo

A continuación se expone todo el código completo para el ejemplo. Para ello, se crea un fichero de texto llamado EjemploBD1.java, y su contenido es el siguiente:

/**********************************************************/ /* AUTOR: Rafael Hernamperez Martin */ /* FECHA: 17-06-2000 */ /* OBJ : Ejemplo simple de acceso a bases de datos */ /**********************************************************/ import java.sql.*; import java.util.Date;

Page 19: JDBC Son Las Siglas de Java DataBase Connectivity

public class EjemploBD1 { public static void main (String args []) { String strSQL = new String ( ); Connection conConexion; Statement staSentencia; ResultSet resResultado;

// Campos del registro long NumPedido = 0; Date Fecha = new Date ( ); String Nombre = new String ( ); long Unidades = 0; String Descripcion = new String ( ); double PVP = 0; double Total = 0;

// Cargar el driver JDBC-ODBC try { Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver"); } catch (Exception e1) { System.out.println ("No se puede cargar el driver JDBC-ODBC"); System.exit (0); }

// Crear la conexion con la base de datos try { conConexion = DriverManager.getConnection ("jdbc:odbc:Almacen", "rafinguer", "rafinguer"); staSentencia = conConexion.createStatement ( );

strSQL = "select Pedidos.Num_Pedido as NumPedido, "; strSQL = strSQL + "Pedidos.Fecha as FechaPedido, "; strSQL = strSQL + "Clientes.Nombre as NombreCliente, "; strSQL = strSQL + "Detalle_Pedidos.Unidades as Cantidad, "; strSQL = strSQL + "Productos.Descripcion as DescProducto, "; strSQL = strSQL + "Productos.PVP as Precio, "; strSQL = strSQL + "(Cantidad * Precio) as Total "; strSQL = strSQL + "from Pedidos, Clientes, "; strSQL = strSQL + "Detalle_Pedidos, Productos where "; strSQL = strSQL + "Pedidos.Cod_Cliente = Clientes.Cod_Cliente and ";

Page 20: JDBC Son Las Siglas de Java DataBase Connectivity

strSQL = strSQL + "Detalle_Pedidos.Cod_Producto = Productos.Cod_Producto and "; strSQL = strSQL + "Detalle_Pedidos.Num_Pedido = Pedidos.Num_Pedido "; strSQL = strSQL + "order by Pedidos.Num_Pedido";

// Ejecucion de la sentencia y generacion del resultado try { resResultado = staSentencia.executeQuery (strSQL);

// Recorrer el resultado while (resResultado.next ( )) { NumPedido = resResultado.getLong ("NumPedido"); Fecha = resResultado.getDate ("FechaPedido"); Nombre = resResultado.getString ("NombreCliente"); Unidades = resResultado.getLong ("Cantidad"); Descripcion = resResultado.getString ("DescProducto"); PVP = resResultado.getDouble ("Precio"); Total = resResultado.getDouble ("Total");

System.out.println ("Num_Pedido : " + NumPedido); System.out.println ("Fecha : " + Fecha); System.out.println ("Cliente : " + Nombre); System.out.println ("Unidades : " + Unidades); System.out.println ("Descripcion: " + Descripcion); System.out.println ("P.V.P. : " + PVP); System.out.println ("Total : " + Total); System.out.println (""); // Linea en blanco (separacion) }

} catch (SQLException e4) { System.out.println ("Hubo un error de SQL: " + e4); System.exit (0); }

} catch (Exception e2) { System.out.println ("No se pudo realizar la conexion"); System.exit (0); }

}

}

Page 21: JDBC Son Las Siglas de Java DataBase Connectivity

Una vez grabado el fichero, se compila el código mediante la siguiente sentencia desde la línea de comandos de la consola de Windows:

javac EjemploBD1.java

Una vez se haya compilado la aplicación sin ningún error, se pasa a la ejecución de la aplicación mediante la siguiente sentencia:

java EjemploBD

En el capítulo anterior se contempló un ejemplo muy sencillo de conexión a una base de datos a través del puente JDBC-ODBC. En este capítulo se abordará más detenidamente esta fase tan fundamental para el acceso a la base de datos.

La carga del driver

La fase previa a la creación de la conexión es la carga del driver adecuado para utilizar la base de datos. De esto se encarga el método forName de la clase Class, y su sintaxis es la siguiente:

Class.forName (“jdbc.nombreDriver”); Class.forName (“empresa.basedatos.driver”);

En el caso de utilizar un driver de tipo JDBC-ODBC, la sentencia a utilizar sería la siguiente:

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

La cadena utilizada posee una sintaxis muy parecida a un URL. La ruta de directorios usual para el acceso a la clase que sirve como driver es la siguiente:

empresa/basedatos/driver.class

Para utilizar otro tipo de controlador habría que remitirse a la documentación del gestor de base de datos que se está utilizando.

Se podría utilizar la clase DriverManager, que es la clase especializada para gestionar los controladores o drivers, pero el método forName de la clase Class es más cómodo, ya que con él no es necesario crear una instancia de la clase DriverManager.

Page 22: JDBC Son Las Siglas de Java DataBase Connectivity

La conexión

Una vez cargado el controlador de la base de datos ya es posible establecer una conexión con la base de datos. La clase Connection se encarga de llevar a cabo este contexto, permitiendo ejecutar sentencias SQL y retornar los valores devueltos por las consultas. También posee la capacidad de ejecutar procedimientos almacenados y de acceder a la información estructural de las tablas.

Para tener una conexión a la base de datos, hay que declarar un objeto de la clase Connection, tal y como ilustra la siguiente línea:

Connection conexion;

Este objeto será una referencia al objeto Connection que retornará el método getConnection de la clase DriverManager. La siguiente línea crea la conexión con la base de datos Almacen:

conConexion = DriverManager.getConnection ("jdbc:odbc:Almacen", "rafinguer", "rafinguer");

El método getConnection está sobrecargado y posee varias sintaxis:

public static Connection getConnection (String url) throws SQLException public static Connection getConnection (String url, String user, String password) throws SQLException public static Connection getConnection (String url, Properties info) throws SQLException

En la primera forma se accede a una base de datos pública que no tiene restringido el acceso, por lo que se pasa solamente la URL de la base de datos, en el siguiente formato:

jdbc:subprotocolo:nombre

En la segunda forma se accede ya a una base de datos con acceso restringido. Además de la URL, se pasa también el nombre de usuario y la contraseña de acceso.

La tercera forma permite suministrar propiedades de conexión. Mediante un objeto de tipo Properties se facilita las propiedades de conexión a la base de datos, mediante la sintaxis tag/valor. Normalmente se pasan los tags user y password.

La clase DriverManager permite también establecer un límite de tiempo para intentar establecer la conexión. Para ello dispone del método setLoginTimeout, cuya sintaxis es la que sigue:

public static void setLoginTimeout (int seconds)

Page 23: JDBC Son Las Siglas de Java DataBase Connectivity

Como parámetro se suministra el número máximo de segundos para la conexión.

Para conocer este tiempo se utiliza el método getLoginTimeout, cuya declaración es la siguiente:

public static int getLoginTimeout ( )

Métodos

Class.forName (“jdbc.nombreDriver”); Class.forName (“empresa.basedatos.driver”); public static Connection getConnection (String url) throws SQLException public static Connection getConnection (String url, String user, String password) throws SQLException public static Connection getConnection (String url, Properties info) throws SQLException public static void setLoginTimeout (int seconds) public static int getLoginTimeout ( )

El uso más habitual de una base de datos es la consulta. Gracias a las consultas se puede acceder a una determinada información, en donde pueden verse involucrados la ordenación, el filtrado de datos o la relación entre dos o más tablas. Para ello, se hace uso de la sentencia SELECT del estándar SQL.

Para llevar a cabo una consulta se debe crear una sentencia asociada al objeto Connection creado. Las sentencias permiten ejecutar acciones tanto de consulta como de actualización, eliminación, inserción, creación, etc.

Existen tres tipos de sentencias:

Statement: Permiten ejecutar sentencias sin ningún tipo de parámetro (simples o directas).

PreparedStatement: Permiten ejecutar sentencias preparadas, con parámetros de entrada. Este tipo de sentencias se utiliza si se va a ejecutar varias veces y si los parámetros son dinámicos en cada ejecución.

Page 24: JDBC Son Las Siglas de Java DataBase Connectivity

CallableStatement: Permiten ejecutar sentencias SQL compiladas (como PreparedStatement), con parámetros de entrada y de salida. Este tipo de sentencias se utiliza para ejecutar procedimientos almacenados.

Este capítulo está centrado en el uso de consultas, por lo que se utilizará como ejemplo una sentencia simple, pues es el tipo de sentencia más habitual. Los detalles sobre cada tipo de sentencia se irán descubriendo a lo largo de este capítulo y los posteriores.

La interface Statement es la interface base de las sentencias. De esta interface derivan el resto de sentencias.

Para llevar a cabo una consulta a la base de datos es preciso crear un objeto de tipo Statement, que será una referencia al tipo Statement devuelto por el objeto Connection, y así poder establecer su asociación. La siguiente línea realiza esto:

Statement sentencia;

El siguiente paso para crear la sentencia es asociar este objeto al objeto Connection, con el fin de que la sentencia que se ejecuta se realiza sobre una determinada base de datos y no sobre otra. Esto se realiza mediante el método getConnection de la clase Connection.

Si anteriormente se creó una conexión mediante un objeto Connection llamado conexion, la forma de crear y asociar la sentencia sería la siguiente:

sentencia = conexion.createStatement ( );

Una vez creada la sentencia y la asociación con el objeto Connection, el siguiente paso es ejecutar una sentencia. En el caso de ejecutar una consulta, hay que tener en cuenta que este tipo de sentencias debe utilizar la sentencia SELECT de SQL, y que esta sentencia retornará un resultado, que es un conjunto de filas y columnas llamado resultset (resultado).

Una forma de saber si la sentencia retorna o no datos es mediante el método execute de la interfaz Statement. Su sintaxis es la siguiente:

public boolean execute (String sql) throws SQLException

Este método ejecuta la sentencia SQL que se pasa como parámetro en forma de cadena o String. Si la sentencia retorna un resultado retornará el valor true. Si la sentencia no devuelve un resultado o la sentencia es de tipo actualización retornará el valor false.

No obstante, cuando se realiza una aplicación, el programador sabe qué tipo de sentencia SQL se va a ejecutar en un momento determinado, es decir, se sabe si se va a realizar una consulta o una actualización.

Page 25: JDBC Son Las Siglas de Java DataBase Connectivity

La forma más directa es utilizar el método executeQuery, el cual ejecuta una sentencia de consulta y retorna el resultado obtenido. Su sintaxis es la siguiente:

public ResultSet executeQuery (String sql) throws SQLException

Obviamente, primero hay que declarar un objeto de tipo ResultSet, que será una referencia al objeto ResultSet retornado por el método executeQuery, y así asociar el resultado a la sentencia. La siguiente sentencia crea un objeto de tipo ResultSet:

ResultSet resultado;

La sentencia SQL se puede escribir en una simple cadena, como ilustra la siguiente línea.

resultado = sentencia.executeQuery (“select * from clientes”);

Si la sentencia SQL es extensa, se puede utilizar un objeto de tipo String, en el cual ir concatenando cada trozo de la sentencia SQL, y pasar dicho objeto String al método executeQuery, tal y como muestra las siguientes líneas de código:

strSQL = "select Pedidos.Num_Pedido as NumPedido, "; strSQL = strSQL + "Pedidos.Fecha as FechaPedido, "; strSQL = strSQL + "Clientes.Nombre as NombreCliente, "; strSQL = strSQL + "Detalle_Pedidos.Unidades as Cantidad, "; strSQL = strSQL + "Productos.Descripcion as DescProducto, "; strSQL = strSQL + "Productos.PVP as Precio, "; strSQL = strSQL + "(Cantidad * Precio) as Total "; strSQL = strSQL + "from Pedidos, Clientes, "; strSQL = strSQL + "Detalle_Pedidos, Productos where "; strSQL = strSQL + "Pedidos.Cod_Cliente = Clientes.Cod_Cliente and "; strSQL = strSQL + "Detalle_Pedidos.Cod_Producto = Productos.Cod_Producto and "; strSQL = strSQL + "Detalle_Pedidos.Num_Pedido = Pedidos.Num_Pedido "; strSQL = strSQL + "order by Pedidos.Num_Pedido"; // Ejecucion de la sentencia y generacion del resultado try { resResultado = staSentencia.executeQuery (strSQL); ... // Tratamiento del resultado de la sentencia } catch (Exception e3) { ... // Tratamiento de la excepcion }

Page 26: JDBC Son Las Siglas de Java DataBase Connectivity

Una vez ejecuta la sentencia de consulta hay un resultado que está referenciado por el objeto ResultSet. La forma de acceso a la información de este resultado se realiza, en primer lugar, por filas o registros.

Cuando se ejecuta la sentencia de consulta se accede antes del primer registro o fila, y sólo se puede acceder a una fila cada vez. Una vez situados en una fila, se puede acceder a cada campo de la fila. El registro actual está apuntado por lo que se denomina un cursor, que es un concepto lógico para indicar la fila en curso.

Para acceder a cada uno de los campos del resultado, hay que tener en cuenta el tipo de dato que posee dicho campo. Cada tipo de dato posee un método getXXX asociado en la interfaz ResultSet. La siguiente tabla ilustra cuál es el tipo de método getXXX recomendado a utilizar para cada tipo de dato:

TIPO METODO TINYINT getByte SMALLINT getShort INTEGER getInt BIGINT getLong REAL getFloat FLOAT getDouble DOUBLE getDouble DECIMAL getBigDecimal NUMERIC getBigDecimal BIT getBoolean CHAR getString VARCHAR getString LONGvARCHAR getAsciiStream BINARY getBytes VARBINARY getBytes LONGVARBINARY getBinaryStream DATE getDate TIME getTime TIMESTAMP getTimeStamp

La sintaxis de cada uno de los métodos getXXX es la siguiente:

byte getByte (int columnIndex) byte getByte (String columnName) short getShort (int columnIndex) short getShort (String columnName) int getInt (int columnIndex) int getInt (String columnName) long getLong (int columnIndex) long getLong (String columnName) float getFloat (int columnIndex) float getFloat (String columnName) double getDouble (int columnIndex)

Page 27: JDBC Son Las Siglas de Java DataBase Connectivity

double getDouble (String columnName) BigDecimal getBigDecimal (int columnIndex) BigDecimal getBigDecimal (String columnName) boolean getBoolean (int columnIndex) boolean getBoolean (String columnName) String getString (int columnIndex) String getString (String columnName) InputStream getAsciiStream (int columnIndex) InputStream getAsciiStrean (String columnName) byte [] getBytes (int columnIndex) byte [] getBytes (String columnName) InputStream getBinaryStream (int columnIndex) InputStream getBinaryStream (String columnName) Date getDate (int columnIndex) Date getDate (String columnName) Time getTime (int columnIndex) Time getTime (String columnName) TimeStamp getTimestamp (int columnIndex) TimeStamp getTimestamp (String columnName)

La sintaxis genérica de los métodos getXXX es bien sencilla. Se puede pasar el número de columna del campo (comenzando desde 1) o el nombre del campo en una cadena.

El acceso a cada fila del resultado ha variado bastante de la especificación de JDBC 1.0. a JDBC 2.0. En la primera, el acceso era bien simple, pues se basaba en un cursor unidireccional y secuencial, que iba desde el primer registro hasta el último. Por ello sólo era necesario un método para acceder a cada uno de los registros. Este método es next, y permite avanzar el cursor a la siguiente fila del resultset, retornando el valor true si hay más registros en el resultset, o el valor false si no hay más registros. La sintaxis de este método es la siguiente:

public boolean next ( ) throws SQLException

En la especificación JDBC 2.0. es posible ya manipular varios tipos de cursores, en lugar del clásico unidireccional. Gracias a este tipo de cursores se puede acceder de manera directa a una determinada fila, volver hacia atrás, o ir al principio o al final del resultset. Para ello, se han incorporado nuevos métodos de acceso, los cuales se detallan a continuación.

public boolean first ( ) throws SQLException public boolean last ( ) throws SQLException public void beforeFirst ( ) throws SQLException public void afterLast ( ) throws SQLException public boolean absolute (int row) throws SQLException public boolean relative (int rows) throws SQLException public void previous ( ) throws SQLException

Page 28: JDBC Son Las Siglas de Java DataBase Connectivity

El método first mueve el cursor o fila actual al primer registro del resultado, retornando el valor true si es válido, o false en caso contrario.

El método last mueve el cursor o fila actual al último registro del resultado, retornando el valor true si es válido, o false en caso contrario.

El método beforeFirst mueve el cursor o fila actual justo antes del primer registro, mientras que el método afterLast, por el contrario, mueve el cursor justo después del último registro del resultado.

El método absolute mueve el cursor o fila actual directamente al número de fila especificado, retornando true si la fila existe, o false en caso contrario. Si el valor pasado es positivo, este valor indica el número de filas desde el primer registro, mientras que, si el valor es negativo, este valor indica el número de filas desde el último registro.

El método relative mueve el cursor o fila actual n filas desde la posición actual, retornando el valor true si la fila existe o es válida, o false en caso contrario. Si el valor positivo el avance de filas será hacia delante, mientras que si es negativo el avance de filas será hacia atrás.

El método previous mueve el cursor o fila actual al registro anterior, retornando el valor true si la fila es válida o existe, o false en caso contrario.

Existen también métodos que permiten comprobar un estado del resultado, y que se pueden consultar antes de acceder a un registro determinado. Estos métodos son los siguientes:

public boolean isBeforeFirst ( ) throws SQLException public boolean isAfterLast ( ) throws SQLException public boolean isFirst ( ) throws SQLException public boolean isLast ( ) throws SQLException public int getRow ( ) throws SQLException

Los cuatro primeros métodos retornan el valor true si el cursor actual está antes del primer registro, después del último registro, en el primer registro o en el último registro, respectivamente, o false en caso contrario.

El método getRow retorna el número de registro de la fila actual, o bien el valor 0 si no existe registro.

Para poder utilizar estos nuevos métodos es necesario definir un resultado desplazable, lo cual se consigue a la hora de crear la sentencia con una nueva sintaxis de la sentencia createStatement:

public Statement createStatement (int resultSetType, int resultSetConcurrency) throws SQLException

Page 29: JDBC Son Las Siglas de Java DataBase Connectivity

Al utilizar esta sintaxis se genera una sentencia que utilizará un resultset de un tipo y concurrencia determinados, que son las nuevas características implementadas en JDBC 2.0.

Los tipos de resultset vienen dados por las siguientes constantes:

ResultSet.TYPE_FORWARD_ONLY ResultSet.TYPE_SCROLL_INSENSITIVE ResultSet.TYPE_SCROLL_SENSITIVE

En el tipo ResultSet.TYPE_FORWARD_ONLY el cursor sólo puede moverse hacia delante.

El tipo ResultSet.TYPE_SCROLL_INSENSITIVE es un tipo de resultset en el que el acceso es deplazable pero que no es sensitivo al cambio de otros usuarios. Esto significa que mientras esté abierto el resultset, si otro usuario realiza algún cambio en alguno de los datos, éstos no se reflejarán (se quedarán en el mismo estado y valor que tenían al abrir el resultset).

El tipo ResultSet.TYPE_SCROLL_SENSITIVE es como el anterior, pero el resultset es sensitivo al cambio de otros usuarios. Esto significa que mientras esté abierto el resultset, si otro usuario realiza algún cambio en alguno de los datos, éstos ser reflejarán en nuestro resultset.

La concurrencia al resultset viene dada por las siguientes constantes:

ResultSet.CONCUR_READ_ONLY ResultSet.CONCUR_UPDATABLE

En el primer caso, la concurrencia es de sólo lectura, mientras que en la segunda es posible realizar operaciones de actualización.

Así, si se desea acceder a los registros de la tabla Clientes, en modo de sólo lectura y que pueda desplazarse en el resultset, habría que crear la sentencia de la siguiente manera:

sentencia = conexion.createStatement ( ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);

El modo estándar, si no se especifica nada en la creación de la sentencia, es del tipo TYPE_FORWARD_ONLY y de concurrencia CONCUR_READ_ONLY, es decir, un resultset no desplazable (el cursor sólo se mueve hacia delante) y de sólo lectura, tal y como hereda de la especificación JDBC 1.0.

Cuando se crea un cursor que no es de tipo TYPE_FORDWARD_ONLY, se puede acceder libremente a los registros (es desplazable), gracias a los métodos vistos anteriormente.

Page 30: JDBC Son Las Siglas de Java DataBase Connectivity

Las sentencias pueden limitarse en cuanto al tiempo de ejecución. El método setQueryTimeout de la interfaz Statement establece el número máximo de segundos que necesita una sentencia para su ejecución. La sintaxis de este método es la que sigue:

public void setQueryTimeout (int seconds) throws SQLException

Para conocer dicho tiempo se utiliza el siguiente método:

public int getQueryTimeout ( ) throws SQLException

Como ha podido apreciarse a lo largo de todo este capítulo, no hay un método que indique el número de filas que posee el resultado. Se puede recurrir a la picardía y hacer lo siguiente: acceder al último registro (método last) y obtener el número de fila actual (método getRow).

Métodos (Connection)

conexion.createStatement ( ); public Statement createStatement (int resultSetType, int resultSetConcurrency) throws SQLException

Métodos (Statement)

public boolean execute (String sql) throws SQLException public ResultSet executeQuery (String sql) throws SQLException public void setQueryTimeout (int seconds) throws SQLException public int getQueryTimeout ( ) throws SQLException

Métodos (ResultSet)

byte getByte (int columnIndex) byte getByte (String columnName) short getShort (int columnIndex) short getShort (String columnName) int getInt (int columnIndex) int getInt (String columnName) long getLong (int columnIndex) long getLong (String columnName) float getFloat (int columnIndex) float getFloat (String columnName)

Page 31: JDBC Son Las Siglas de Java DataBase Connectivity

double getDouble (int columnIndex) double getDouble (String columnName) BigDecimal getBigDecimal (int columnIndex) BigDecimal getBigDecimal (String columnName) boolean getBoolean (int columnIndex) boolean getBoolean (String columnName) String getString (int columnIndex) String getString (String columnName) InputStream getAsciiStream (int columnIndex) InputStream getAsciiStrean (String columnName) byte [] getBytes (int columnIndex) byte [] getBytes (String columnName) InputStream getBinaryStream (int columnIndex) InputStream getBinaryStream (String columnName) Date getDate (int columnIndex) Date getDate (String columnName) Time getTime (int columnIndex) Time getTime (String columnName) TimeStamp getTimestamp (int columnIndex) TimeStamp getTimestamp (String columnName) public boolean next ( ) throws SQLException public boolean first ( ) throws SQLException public boolean last ( ) throws SQLException public void beforeFirst ( ) throws SQLException public void afterLast ( ) throws SQLException public boolean absolute (int row) throws SQLException public boolean relative (int rows) throws SQLException public void previous ( ) throws SQLException public boolean isBeforeFirst ( ) throws SQLException public boolean isAfterLast ( ) throws SQLException public boolean isFirst ( ) throws SQLException public boolean isLast ( ) throws SQLException public int getRow ( ) throws SQLException

Constantes

ResultSet.TYPE_FORWARD_ONLY ResultSet.TYPE_SCROLL_INSENSITIVE ResultSet.TYPE_SCROLL_SENSITIVE ResultSet.CONCUR_READ_ONLY ResultSet.CONCUR_UPDATABLE