Una de las primeras cosas que haremos cuando estemos utilizando una base de datos desde un programa Java con JDBC será hacer consultas.
Si nos centramos en cualquier tipo de aplicación lo normal es que el tipo de sentencia hacia las bases de datos más utilizado sea la consulta. Bastante más que las inserciones, actualizaciones y borrados.
El caso normal y lógico ante un entorno optimizado es la realización de consultas cerradas. Donde están claramente definidos los campos que se quieren recuperar, así como los índices de acceso a los datos.
Cierto es que se puede construir consultas donde los campos sean variables, incluso sus filtros. Si bien, dichas consultas solo nos traerán quebraderos de cabeza y mucho tiempo en busca de la optimización.
No quiero decir que esto no se deba de hacer, ya que hay ciertos casos donde si que son útiles. Pero por norma general deberemos de acostumbrarnos a definir bien nuestras consultas y hacerlas cerradas.
En este ejemplo vamos a hacer una consulta que ¡No deberíais de poner nunca en producción¡. Pero que es útil para demostraros el uso de JDBC.
La consulta en cuestión será:
SELECT * FROM personas
Imaginaros la cantidad de campos y filas que puede tener una tabla de este calibre dentro de una gran empresa. Vamos, que seríamos objeto de las iras de los administradores de bases de datos si intentásemos lanzar esta consulta en un entorno de producción.
A nosotros nos va a servir en el ejemplo ya que la idea es listar el contenido de la tabla, desconociendo el número de filas y columnas que esta contiene. A si que empecemos….
Lo primero será cargar los drivers de acceso a la base de datos y realizar la conexión. En nuestro caso vamos a utilizar los drivers de una base de datos MySQL «com.mysql.jdbc.Driver», pero puedes utilizar cualquiera. Si no sabes cuales son los drivers de tu base de datos siempre podrás utilizar el driver para ODBC. «sun.jdbc.odbc.JdbcOdbcDriver».
String sDriver = "com.mysql.jdbc.Driver";
String sURL = "jdbc:mysql://localhost:3306/mibasededatos";
try{
Class.forName(sDriver).newInstance();
con = DriverManager.getConnection(sURL,"root","password");
} catch (SQLException sqle){
sqle.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
Como podemos ver en el código, es la clase DriverManager la que nos permite establecer la conexión con la url, un usuario y un passoword. Ya que el acceso a la base de datos y para este caso (aunque suele ser normal) necesita de autentificación.
Lo siguiente que vamos a realizar es definir la sentencia de consulta (nuestra SELECT) y ejecutarla. Para ello definiremos una clase PreparedStatement para la consulta y una clase ResulSet para almacenar el conjunto de resultados.
PreparedStatement stmt = null;
ResultSet rs = null;
stmt = con.prepareStatement("SELECT * FROM personas");
rs = stmt.executeQuery();
La ejecución de la sentencia se hace con el método .executeQuery() y los resultados se almacenan en el ResulSet.
Ahora llega el momento de indagar cuantas columnas tiene nuestra consulta. Ya que nuestra poca disposición ante las consultas optimizadas nos ha llevado a escribir el «SELECT *».
La información de las columnas va en los metadatos de la consulta. Los metadatos es información relacionada con el conjunto de resultados obtenidos. Para acceder a la información de los metadatos tenemos el método .getMetaData() dentro del ResulSet.
Este método devolverá otro ResulSet, pero con meta-información. De esta meta-información utilizaremos dos métodos:
- getColumnCount(), que nos dice el número de columnas que hay en la consulta.
- getColumnName(id), que dado un id de columna nos devuelve su nombre.
Lo que vamos a hacer es recorrer mediante un bucle todas las columnas y mostrar sus nombres.
for (int x=1;x<=rs.getMetaData().getColumnCount();x++)
System.out.print(rs.getMetaData().getColumnName(x)+ "\t");
Una vez impresas en pantalla las columnas de la consulta solo nos quedará el listar el contenido de la misma. En este caso los métodos .getXXX() deberán de ser utilizados mediante un número y no el nombre de la columna (ya que os recuerdo que no le sabemos). Es por ello que nos volveremos a apoyar en el método .getColumnCount() para ir listado los datos. El código que nos queda es el siguiente:
while(rs.next()) {
for (int x=1;x<=rs.getMetaData().getColumnCount();x++)
System.out.print(rs.getString(x)+ "\t");
System.out.println("");
}
Para iterar sobre el ResulSet utilizamos el método .next(). Dicho método devolverá un valor false (que será el que nos ayude a salir del bucle) cuando no haya más registros.
Solo nos quedará cerrar la conexión a la base de datos. Como todo el código de acceso a la base de datos está entre un try-catch. Ya que puede saltar una excepción SQLException en cualquier momento. La idea es utilizar la parte finally del try-catch para cerrar las conexiones. El finally se ejecuta siempre, independientemente de que se haya producido una excepción o no.
try{
...
} catch (SQLException sqle){
sqle.printstacktrace();
} finally {
if (con != null) {
try{
rs.close();
stmt.close();
con.close();
} catch(Exception e){
e.printStackTrace();
}
}
}