Ejemplo: Crear los DAO (parte 3)

En la última parte dedicada a DAOs, muestro cómo crear los métodos que permiten obtener elementos de la base de datos convirtiendo un ResultSet en un objeto.

Hay una versión nueva de este curso. Haz clic aquí para revisar JDBC, la versión actualizada de este curso.

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.

Lista de reproducción
  1. 1
    Presentación de JDBC
    4 minutos
  2. 2
    Instalando MySQL
    7 minutos
  3. 3
    Creando tablas
    9 minutos
  4. 4
    Agregando el driver JAR
    7 minutos
  5. 5
    Estableciendo la conexión
    8 minutos
  6. 6
    Statement y ResultSet
    9 minutos
  7. 7
    Bobby Tables y PreparedStatement
    8 minutos
  8. 8
    Transacciones y MySQL
    6 minutos
  9. 9
    Transacciones, commits y rollbacks (parte 1)
    7 minutos
  10. 10
    Transacciones, commits y rollbacks (parte 2)
    6 minutos
  11. 11
    Ejemplo: Crear modelos
    9 minutos
  12. 12
    Ejemplo: Crear los DAO (parte 1)
    10 minutos
  13. 13
    Ejemplo: Crear los DAO (parte 2)
    12 minutos
  14. 14
    Ejemplo: Crear los DAO (parte 3)
    13 minutos
  15. 15
    Ejemplo: DAO Manager
    12 minutos
  16. 16
    Ejemplo: CRUD Alumnos (parte 1)
    15 minutos
  17. 17
    Ejemplo: CRUD Alumnos (parte 2)
    14 minutos
  18. 18
    Ejemplo: CRUD Alumnos (parte 3)
    13 minutos
  19. 19
    Ejemplo: CRUD Profesores
    25 minutos
  20. 20
    Ejemplo: CRUD Asignaturas
    alrededor de 1 hora
  21. 21
    Ejemplo: Login (final adelantado)
    17 minutos
  22. 22
    Conectar a PostgreSQL en Java con JDBC
    8 minutos
  23. 23
    Conectar a PostgreSQL en Kotlin con JDBC
    7 minutos
  24. 24
    Conectar a PostgreSQL en Java con JDBC (con NetBeans)
    10 minutos