6. Fuentes de datos

6.1. Introducción a JDBC

En la mayoría de las aplicaciones que nos vamos a encontrar, aparecerá una base de datos como fuente de información. JDBC nos va a permitir acceder a bases de datos (BD) desde Java. Con JDBC no es necesario escribir distintos programas para distintas BD, sino que un único programa sirve para acceder a BD de distinta naturaleza. Incluso, podemos acceder a más de una BD de distinta fuente (Oracle, Access, MySql, etc.) en la misma aplicación. Podemos pensar en JDBC como el puente entre una base de datos y nuestro programa Java.

Un programa Java que utilice JDBC primero deberá establecer una conexión con el SGBD (MySQL, Oracle, Access, etc). Para realizar dicha conexión haremos uso de un driver específico para cada SGBD que estemos utilizando. Una vez establecida la conexión ya podemos interrogar la BD con cualquier comando SQL (select, update, create, etc.).

6.2. Los drivers

Los drivers para poder acceder a cada SGBD no forman parte de la distribución de Java por lo que deberemos obtenerlos por separado.

Para instalar el driver lo único que deberemos hacer es incluir el fichero JAR que lo contiene en el CLASSPATH. Con el driver instalado, podremos cargarlo desde nuestra aplicación simplemente cargando dinámicamente la clase correspondiente al driver. Por ejemplo, para MySQL:

Class.forName("com.mysql.jdbc.Driver");  

Java incorpora un driver para JDBC-ODBC. Es útil, por ejemplo, para conectar con base de datos Access, definiendo el origen ODBC previamente en Windows. Este driver se carga como se muestra a continuación:

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

6.3. Conectar a la BD

Una vez tenemos los drivers cargados con el código anterior, ya podremos conectar con la BD en cuestión. Para ello, utilizaremos alguno de los métodos :

Connection con = DriverManager.getConnection(url);  
Connection con = DriverManager.getConnection(url, login, password);

El primero se utiliza cuando se puede conectar sin autentificar a la BD.

Por ejemplo, para conectar por MySQL con una BD llamada "prueba" en la máquina local, con un usuario "root" y password "root", pondríamos algo como:

Connection con = 
DriverManager.getConnection("jdbc:mysql://localhost/prueba", "root", "root");

Si esta misma conexión la quisiéramos hacer por ODBC sería:

Connection con = DriverManager.getConnection("jdbc:odbc:prueba",...);

6.4. Operaciones contra la BD

Una vez obtenida la conexión a la BD, podemos utilizarla para realizar consultas, inserción y/o borrado de datos de dicha BD. Todas estas operaciones se realizarán mediante lenguaje SQL. La clase Statement es la que permite realizar todas estas operaciones. La instanciación de esta clase se realiza haciendo uso del siguiente método que proporciona el objeto Connection:

Statement stmt = con.createStatement();

6.4.1. Consultas

Para obtener datos almacenados en la BD podemos realizar una consulta SQL (query). Podemos ejecutar la consulta utilizando el objeto Statement, pero ahora haciendo uso del método executeQuery al que le pasaremos una cadena con la consulta SQL. Los datos resultantes nos los devolverá como un objeto ResultSet.

String query = "SELECT * FROM ALUMNOS WHERE sexo = 'M'";  
ResultSet result = stmt.executeQuery(query);

El objeto ResultSet dispone de un cursor que estará situado en el registro que podemos consultar en cada momento. Este cursor en un principio estará situado en una posición anterior al primer registro de la tabla. Podemos mover el cursor al siguiente registro con el método next del ResultSet. La llamada a este método nos devolverá true mientras pueda pasar al siguiente registro, y false en el caso de que ya estuviéramos en el último registro de la tabla. Para la consulta de todos los registros obtenidos utilizaremos normalmente un bucle como el siguiente:

while(result.next()) {        
	// Leer registro
}

Ahora necesitamos obtener los datos del registro que marca el cursor, para lo cual podremos acceder a los campos de dicho registro. Esto lo haremos utilizando los métodos getXXXX(campo) donde XXXX será el tipo de datos de Java en el que queremos que nos devuelva el valor del campo. Hemos de tener en cuenta que el tipo del campo en la tabla debe ser convertible al tipo de datos Java solicitado. Para especificar el campo que queremos leer podremos utilizar bien su nombre en forma de cadena, o bien su índice que dependerá de la ordenación de los campos que devuelve la consulta. También debemos tener en cuenta que no podemos acceder al mismo campo dos veces seguidas en el mismo registro. Si lo hacemos nos dará una excepción.

Si queremos imprimir todos los datos obtenidos de nuestra tabla ALUMNOS del ejemplo podremos hacer lo siguiente:

int exp;  
String nombre;  
String sexo;    


while(result.next()) {      
	exp = result.getInt("exp");      
	nombre = result.getString("nombre");
	sexo = result.getString("sexo");
	System.out.println(exp + "\t" + nombre + "\t" + sexo); 
}

6.4.2. Actualizaciones

Las actualizaciones (inserciones, borrados y modificaciones) en una BD se realizan mediante el objeto Statement, pero ahora haciendo uso del método executeUpdate al que le pasaremos una cadena con la operación SQL. Nos devolverá un entero indicando cuántas filas se han visto afectadas por la operación (si el número de filas fuese 0, significará que no ha podido realizarla).

String upd = "INSER INTO ALUMNOS (exp, nombre, sexo)
VALUES(1234, 'Pepe Gómez', 'M')"; int res = stmt.executeUpdate(upd); ... if (res == 0) System.err.println("Error al realizar la operacion");

6.5. Fuentes de datos con servidores web

Si estamos realizando una aplicación web, podemos acceder a las bases de datos de nuestra aplicación desde nuestros servlets y páginas JSP con el código que hemos visto aquí. Sin embargo, también tenemos otra alternativa. En Tomcat, por ejemplo, podemos definir la conexión a una base de datos mediante una fuente de datos (DataSource), especificando los parámetros de conexión en un fichero XML (normalmente el fichero META-INF/context.xml, dentro de la aplicación web):

<?xml version="1.0" encoding="ISO-8859-1"?>
<Context>
    <Resource
        name="jdbc/alumnos"
        type="javax.sql.DataSource"
        auth="Container"
        username="root"
        password="root"
        driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://localhost:3306/alumnos?autoReconnect=true"/>
            
        <ResourceParams name="miBD">
            
            <parameter>
                <name>maxActive</name>
                <value>20</value>
            </parameter>
            
            <parameter>
                <name>maxIdle</name>
                <value>5</value>
            </parameter>
            
            <parameter>
                <name>maxWait</name>
                <value>10000</value>
            </parameter>
            
        </ResourceParams>

</Context>

Notar que indicamos la URL de la BD, el nombre del driver, usuario y password (como hacíamos mediante código para conectar). También podemos especificar (en ResourceParams) un pool de conexiones para mantener varias abiertas y solventar problemas de concurrencia en el acceso.

Después, para conectar con esta BD desde algún servlet, JSP, o clase Java interna que utilicemos en nuestra aplicación web, usaremos un código como:

Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
// Después buscamos el DataSource con el nombre // (atributo name del Resource del fichero XML) que hayamos indicado DataSource ds = (DataSource)envCtx.lookup("jdbc/alumnos"); Connection con = ds.getConnection();
//A partir de aquí, ya creamos las sentencias SQL igual que antes: Statement stmt = con.createStatement(); ...