Realizar una consultas

Para realizar cualquier acción sobre la base de datos (consulta, insertar nuevos registros, modificar los existentes o borrar), necesitamos una clase PreparedStatement. Para obtenerla, se le pide dicha clase a la conexión.
La forma de hacerlo, para una consulta, es la siguiente:
// Preparamos la consulta 
String sql="select * from categorias";
PreparedStatement sentencia = conexion.prepareStatement(sql);  
ResultSet resultado = sentencia.executeQuery();
La parte de prepareStatement() puede lanzar una excepción que hay que capturar.
El PreparedStatement obtenido tiene un método executeQuery() para leer datos y executeUpdate() para insertar, actualizar y eliminar datos. executeQuery() sirve para realizar una consulta a base de datos.
  • El parámetro que se pasa en un String en el que está la consulta en lenguaje SQL. No hace falta terminarlo con punto y coma. En nuestro caso "select * from categorias". siendo categorias el nombre que hemos puesto a la tabla en la base de datos.
  • El resultado nos lo devuelve el método como un ResultSet. Este ResultSet no es más que una clase java similar a una lista en la que está el resultado de la consulta. Cada elemento de la lista es uno de los registros de la base de datos. En realidad, ResulSet no contiene todos los datos, sino que los va consiguiendo de la base de datos según se van pidiendo. Por ello, el método executeQuery() puede tardar poco, pero el recorrer los elementos del ResultSet no es tan rápido. De esta forma se evita que una consulta que dé muchos resultados tarde mucho tiempo y llene la memoria del programa java.

Leer los resultados

El ResultSet contiene dentro los registros leidos de la base de datos. Inicialmente, tal cual nos lo devuelve el sentencia.executeQuery(), tiene internamente un "puntero" apuntando justo delante del primer registro. El método next() del ResultSet hace que dicho puntero avance al siguiente registro, en este caso, al primero. Si lo consigue, el método next() devuelve true. Si no lo consigue (no hay siguiente registro que leer), devuelve false.
Por tanto, una forma de ir leyendo los registros en meternos en un while.
// Recorremos el resultado, mientras haya registros para leer, y escribimos el resultado en pantalla. 
while (resultado.next())  {      
...
}
Una vez que el "puntero" está apuntando a un registro, los métodos getInt()getString()getDate(), etc nos van devolviendo los valores de los campos de dicho registro. Podemos pasar a estos métodos un índice (que comienza en 1) para indicar qué columna de la tabla de base de datos deseamos. También podemos usar un String con el nombre de la columna (tal cual está en la tabla de base de datos).
Es responsabilidad nuestra saber qué tipo de dato hay en cada columna, aunque si nos equivocamos y RecordSet es capaz de hacer la conversión, la hará por nosotros. Por ejemplo, en cualquiera de los campos anteriores podemos pedir un getString() y nos devolveran los números como String y la fecha como String.

Cerrar la conexión

Una vez que terminamos de usar la conexión, se debería cerrar, o bien terminar el programa, con lo que se cierra automáticamente.
// Cerramos la conexion a la base de datos.  conexion.close()