|
JDBC y ODBC
La capacidad para acceder a bases de datos desde Java la ofrece la API
JDBC (Java DataBase Conectivity). JDBC es un estándar para
manejar bases de datos en Java. ODBC es un estándar de Windows
para manejar bases de datos, de forma que cualquier programa en Windows
que desee acceder a bases de datos genéricas debe usar este estándar.
La necesidad de crear un estándar propio para acceder a bases de
datos desde Java se explica porque el estándar ODBC está
programado en C y un programa que use este estándar, por lo tanto,
depende de la plataforma.
Controladores JDBC-ODBCNecesitamos acceder a un origren de datos ODBC pero contamos con una
API que usa el estándar JDBC. Para solventar este problema las
empresas realizan drivers que traducen el ODBC a JDBC. Hay varios tipos
de Driver, pero para nuestro ejemplo usaremos los llamados puentes JDBC-ODBC.
Estamos de suerte porque el JDK de Windows incorpora el driver necesario
para conectar bases de datos Access.
Crear un nuevo DSN (Data Source Name)Para realizar la conexión a una base de datos ODBC necesitaremos
crear un perfil DSN desde el panel de control y posteriormente accederemos
a la base de datos a partir del nombre del perfil. En el perfil DSN lo
que se hace es indicar el driver a utilizar, así como el archivo
o archivos del origen de datos. Estos son los pasos a llevar a cabo para
configurar un perfil DSN.
1.- Iremos a Panel de Control. Ello se hace desde Inicio->Configuración
o desde MiPC.
2.- Ahora hacemos doble-click en el icono de Fuentes de datos ODBC
(32 bits).
3.- En nuestra pantalla aparecerá ahora la pestaña DSN
usuario seleccionada. Para crear un nuevo perfil haremos click en
Agregar...
4.- A continuación se nos pide que ingresemos el controlador que
vamos a usar en el nuevo perfil. En nuestro caso será Microsoft
Access Driver (*.mdb).
5.- Una vez aquí sólo nos queda dar un nombre al origen
de datos y especificar el archivo .mdb de origen. Tras aceptar la ventana
ya tenemos creado un perfil con lo que ya podemos comenzar a programar.
Clases, objetos y métodos básicosLo que necesitamos para hacer nuestro programa es la API JDBC incluida
en la última versión del JDK. El paquete a utilizar y el
cual deberemos importar es el paquete java.sql
Las primeras líneas de código suelen ser rutinarias ya
que siempre serán muy similares.
Cargar el DriverLo primero es hacer una llamada al Driver JDBC-ODBC para cargarlo. Eso
se consigue con las siguientes líneas de código:
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); }
catch(Exception e){ System.out.println("No se ha podido cargar el
Driver JDBC-ODBC"); }
Con esto ya tenemos cargado el Driver. Ahora básicamente trabajaremos
con tres objetos. Estos objetos son: Connection, Statement
y ResultSet. El objeto Connection se obtiene al realizar la conexión
a la base de datos. El objeto Statement se crea a partir del anterior
y nos permite ejecutar SQL para hacer consultas o modificaciones en la
base de datos. En caso de hacer una consulta (SELECT ... FROM ...) se
nos devolverá un objeto que representa los datos que deseamos consultar;
este objeto es un objeto ResultSet (Hoja de resultados).
El objeto ConnectionDebemos realizar la conexión a nuestro origen de datos. Para ello
debemos crear un objeto Connection de la siguiente forma:
Connection con = DriverManager.getConnection("jdbc:odbc:Nombre_Perfil_DSN",
"Nombre_Usuario", "Contraseña");
Los dos últimos parámetros pueden ser cadenas vacías
"" a no ser que la base de datos las requiera. Con esto ya hemos
realizado una conexión a nuestra base de datos. Pero esto todavía
no es suficiente. Ahora vamos a crear un objeto Statement con el que podremos
ejecutar y hacer consultas SQL. Si hasta ahora todo ha sido rutinario
a partir de ahora vamos a poder crear código más adaptado
a las necesidades de nuestro programa.
El objeto StatementComo se ha dicho, un objeto Statement se crea a partir del objeto Connection
antes obtenido. También como se ha dicho un objeto Statement nos
permite hacer consultas SQL que nos devuelven una hoja de resultados.
Pues bien, según como deseamos que sea esa hoja de resultados (modificable,
o no, sensible a las modificaciones o no,...) deberemos crear de una forma
u otra el objeto Statement. Más adelante se explican las diferencias
entre crearlos de una u otra forma. De momento nos limitaremos ha hacerlo
de la forma más sencilla.
Statement stat = con.createStatement();
De esta forma muy simple hemos creado un objeto Statement. Ahora podemos
usar este objeto Statement para hacer modificaciones en la base de datos
a través del lenguaje SQL. Para realizar modificaciones, es decir,
instrucciones INSERT, UPDATE o DELETE, se usa el método executeUpdate
pasando como parámetro una cadena de texto String que contenga
la instrucción SQL.
Para hacer una consulta, es decir, una instrucción SELECT debemos
usar otro método: el método executeQuery que como
el anterior se le ha de pasar un String que contenga la instrucción.
Este método nos devuelve un objeto ResultSet que contiene los datos
obtenidos. Este objeto será diferente según como hayamos
creado el objeto Statement. En el ejemplo anterior hemos usado un método
muy simple de Connection para crear el objeto Statement, pero hay otras
formas de crearlo. Estas son y estas son las características que
aportan a la hoja de resultados de una consulta:
El método anteriormente utilizado es el siguiente: createStatement(),
pero existe el mismo método al que le podemos pasar dos parámetros.
En la documentación se expresa así: createStatement(int
resultSetType, int resultSetConcurrency). Los posibles valores a pasar
son campos de la clase ResultSet. Por ejemplo para el parámetro
resultSetType podemos elegir que el objeto ResultSet se pueda mover (entre
registros) sólo hacia delante (ResultSet.TYPE_FORWARD_ONLY), que
se pueda mover pero que cuando se actualice, aunque los cambios ya hayan
sido reflejados en la base de datos, el ResultSet no los 'sienta' (ResultSet.TYPE_SCROLL_INSENSITIVE)
o que se pueda mover y que los cambios si que se reflejen también
en él (ResultSet.TYPE_SCROLL_SENSITIVE). Para el parámetro
resultSetConcurrency podemos establecer dos valores diferentes: ResultSet.CONCUR_READ_ONLY
si queremos que los datos se puedan leer pero no actualizar, y ResultSet.CONCUR_UPDATABLE
si queremos permitir que la base de datos sea actualizable mediante el
objeto ResultSet. Si no se usa el método sin parámetros
el objeto será TYPE_FORWARD_ONLY y CONCUR_READ_ONLY.
El objeto ResultSet: Hoja de resultadosMoverse por la hoja de resultados
Al hablar de posición del cursor nos referimos a la posición
dentro de los datos del objeto ResultSet. Lo primero que hay que saber
es que el cursor tiene tantas posiciones como filas tenga la consulta
y dos más que se sitúan antes de la primera fila y después
de la última. Nada más crear un objeto ResultSet, la posición
del cursor es la anterior a la primera fila.
Para mover el cursor a la posición siguiente usaremos el método
next() que nos devuelve una variable booleana: sí, si se
ha podido mover; no, si no ha sido posible el desplazamiento. Nos devolverá
false si estamos en el útimo registro (el posterior al último).
Para movernos hacia atrás tenemos un método muy similar:
el método previous() que al igual que el anterior nos devuelve
un valor booleano que será false si estamos en el registro anterior
al primero. Estos métodos nos permiten movernos de forma relativa
por la hoja de resultados; si deseamos movernos a un registro determinado
usaremos el método absolute(int numero_fila), que también
nos devuelve un valor boolean. Además tenemos otros métodos
que son: afterLast(), que mueve el cursor a la fila posterior a
la última; beforeFirst() que mueve el cursor a la fila anterior
a la primera; last() que mueve el cursor a la última fila;
first() que mueve el cursor a la primera fila. Todos ellos devuelven
un valor booleano.
Obtener datos de la hoja de resultados
Para acceder a los datos de la hoja de resultados usamos los métodos
get...(int numeroColumna) o get...(String nombreColumna).
Estos métodos nos devuelven el valor que indica el nombre del método
(por ejemplo tenemos: getString, getInt, getDate, ...) indicando el número
o el nombre de la columna. Hay que tener en cuenta que el número
de columna es el número de columna en la hoja de resultados y por
tanto se establece con el orden en el que se han incluido las columnas
en la instrucción SELECT. Por ejemplo si hemos hecho la consulta
de la siguiente forma: SELECT Nombre, Apellidos ... la columna Nombre
será la primera y la columna Apellidos será la segunda independientemente
de cómo estén situadas en la base de datos. Si hacemos un
SELECT * FROM ..., en ese caso las columnas estarán en el orden
en el que están en la base de datos.
Modificar la base de datos con el objeto ResultSet
Hemos dicho que mediante el objeto Statement podemos ejecutar sentencias
SQL para modificar la base de datos y hacer consultas, por lo que podemos
usar el lenguaje SQL para hacer cualquier operación en la base
de datos; pero además tenemos métodos especializados que
nos permiten hacer estas mismas tareas sin usar el lenguaje SQL. Para
ello se usan los métodos especializados del objeto ResultSet. Por
tanto si deseamos modificar la base de datos a través de Java,
sin utilizar SQL, lo primero que deberemos hacer es realizar una consulta
SQL para obtener el objeto ResultSet (parece un poco paradógico).
Ahora sólo nos queda usar los métodos especializados de
este objeto.
Por ejemplo podemos usar deleteRow() para borrar una fila.
Para actualizar una fila se usan los métodos update...(NombreColumna,
valor) o update...(NumeroColumna, valor), así podemos
encontrar updateFloat, updateString, ... Para que los cambios se reflejen
en la base de datos se debe llamar al método updateRow()
o cancelRowUpdates() si queremos cancelar la actualización.
resultset.updateString("Nombre", "PEPE");
resultset.updateRow();
Para insertar una fila nos hemos de mover a un lugar del cursor especial
con el método toInsertRow(), una vez allí usaremos
los métodos update... explicados antes y para reflejar esta actualización
llamar al método insertRow().
|