En esta ocasión nos centramos en cómo implementar las operaciones para obtener uno o todos los registros desde una base de datos y convertir esos datos en objetos Java personalizados. Hasta ahora habíamos trabajado con operaciones de actualización, pero cuando queremos recuperar información, el proceso cambia porque entran en juego los ResultSet y la navegación por sus datos.
El punto clave es la función que convierte un ResultSet en un objeto, por ejemplo, un alumno. Esta función es fundamental porque tanto la operación de obtener uno como la de obtener todos devuelven un ResultSet que debemos recorrer y transformar en objetos Java. Para ello, identificamos los campos que necesitamos extraer, como el nombre, apellidos y fecha de nacimiento, que son los datos obligatorios para construir nuestro objeto alumno.
Para extraer estos datos usamos métodos como getString para cadenas o getDate para fechas, aplicándolos sobre el ResultSet con el nombre de la columna correspondiente. Por ejemplo, para obtener el nombre haríamos algo como rs.getString("nombre"). En el caso de la fecha, que es un tipo java.sql.Date, podemos usarlo directamente o convertirlo a java.util.Date si es necesario.
Una vez extraídos los datos, creamos el objeto alumno con el constructor que recibe nombre, apellidos y fecha de nacimiento. Luego, si el registro tiene un identificador, lo asignamos con un método setter, usando rs.getLong("id_alumno"). Finalmente, devolvemos el objeto alumno ya construido.
Para implementar el método que obtiene un alumno dado su identificador, creamos un PreparedStatement con la consulta SQL correspondiente. Asignamos el parámetro del identificador con stat.setLong(1, id) y ejecutamos la consulta con executeQuery(), que nos devuelve un ResultSet. Comprobamos si el resultado tiene datos con rs.next(). Si no hay resultados, lanzamos una excepción indicando que no se encontró el registro. Si sí hay datos, usamos la función de conversión para crear el objeto alumno a partir del ResultSet.
Es importante cerrar siempre el ResultSet y el PreparedStatement en un bloque finally para liberar recursos y evitar problemas de conexión. Además, cualquier excepción SQL la encapsulamos en una excepción propia del DAO para no exponer detalles de la base de datos a capas superiores.
Para obtener todos los alumnos, el proceso es similar, pero en lugar de usar un if con rs.next(), usamos un while para recorrer todos los registros. Creamos una lista de alumnos y en cada iteración añadimos un nuevo objeto convertido desde el ResultSet. Si la tabla está vacía, simplemente devolvemos una lista vacía, lo cual es un comportamiento válido y esperado.
Aunque en este ejemplo usamos PreparedStatement para ambas operaciones, en el caso de obtener todos los registros podríamos usar un Statement simple, ya que no hay parámetros que asignar. Sin embargo, mantener el uso de PreparedStatement es una buena práctica por consistencia y seguridad.
Este enfoque manual de convertir ResultSet en objetos es bastante común, aunque en proyectos más avanzados se suele usar un ORM como JPA o Hibernate, que automatizan este proceso y simplifican mucho el código.
Para probar lo implementado, podemos crear un método main donde establecemos una conexión con la base de datos usando DriverManager.getConnection(). Creamos una instancia del DAO y llamamos al método para obtener todos los alumnos. Luego, recorremos la lista e imprimimos cada alumno, aprovechando que la clase tiene un método toString bien definido.
También podemos probar a insertar un nuevo alumno creando un objeto con los datos necesarios y llamando al método de inserción del DAO. Un detalle a tener en cuenta es que el identificador del alumno suele ser generado por la base de datos, por lo que no deberíamos asignarlo manualmente al crear un nuevo registro. Este es un aspecto que conviene corregir para evitar bugs.
Con estas operaciones básicas implementadas, tenemos un DAO funcional para manejar la recuperación y almacenamiento de alumnos en la base de datos, con un manejo adecuado de recursos y excepciones, y una estructura clara para convertir datos SQL en objetos Java.