Ejemplo: CRUD Alumnos (parte 1)

Creando un JFrame con una JTable y un JTableModel que use el patrón Adapter para permitir representar los alumnos procedentes del DAO en forma de modelo que podamos incorporar a nuestra tabla.

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

Para gestionar correctamente las claves compuestas en nuestros DAOs, es fundamental entender que no siempre podemos usar un único tipo simple como long para la clave primaria. En el caso de la entidad matrícula, cuya clave está compuesta por el alumno, la asignatura y el año, la solución adecuada es encapsular estos campos dentro de una estructura interna, que llamamos IdMatricula. Esta subestructura pública contiene sus propios getters, setters y constructores, y se integra dentro de la clase matrícula para reflejar que forma parte de ella. Así, en lugar de acceder directamente a matricula.alumno, ahora lo hacemos mediante matricula.getId().getAlumno(), lo que mantiene la coherencia con la clave compuesta.

Además, hemos ampliado el DAO de matrícula para incluir métodos que permiten obtener todas las matrículas de un alumno, de una asignatura o de un curso concreto. Esto facilita consultas más específicas sin complicar demasiado el SQL, aunque podríamos extenderlo aún más si fuera necesario.

Un detalle importante al trabajar con bases de datos es el manejo de valores null, especialmente en campos como la nota, que puede no estar asignada aún. Al insertar datos, debemos indicar explícitamente cuando un campo es null usando métodos específicos para ello. Pero el verdadero reto está al leer esos valores: los métodos como getInt o getLong devuelven cero si el valor es null en la base de datos, lo que puede confundirnos si cero es un valor válido. Por eso, es imprescindible usar el método wasNull justo después de leer el valor para saber si realmente era null o un cero legítimo. Este cuidado evita errores lógicos en nuestra aplicación.

Pasando a la interfaz gráfica, hemos creado un nuevo paquete llamado frames donde desarrollamos un frame llamado ListaAlumnosFrame. Empezamos con una estructura sencilla: un layout tipo border, una barra de herramientas con botones para acciones como insertar o eliminar (aunque inicialmente solo uno para evitar que la barra quede demasiado pequeña), y una tabla para mostrar los alumnos.

En Swing, las tablas (JTable) se basan en un modelo llamado TableModel, que define el número de filas y columnas, los nombres de las columnas y los valores que se muestran en cada celda. En lugar de usar el modelo por defecto, hemos optado por crear un modelo personalizado que extiende de AbstractTableModel. Este modelo recibe un DAO de alumnos y actúa como adaptador para convertir la lista de alumnos en datos que la tabla pueda mostrar.

Para simplificar el código generado automáticamente por NetBeans, eliminamos elementos innecesarios como el tema Nimbus y convertimos algunos métodos a expresiones lambda. Luego, establecemos la conexión con la base de datos a través de un DAOManager, que hemos diseñado como un singleton parcial para evitar múltiples instancias, aunque no es un singleton estricto porque no es estático.

El método clave en nuestro AlumnosTableModel es getValueAt, que recibe la fila y la columna solicitadas y devuelve el valor correspondiente. Por ejemplo, en la columna 0 devolvemos el ID del alumno, en la 1 los apellidos, en la 2 el nombre, y en la 3 la fecha de nacimiento formateada con un DateFormat. Si ocurre algún problema con la fecha, devolvemos null para evitar errores.

Finalmente, asignamos nuestro modelo personalizado a la tabla con this.tabla.setModel(model). Al ejecutar la clase, la ventana muestra la lista de alumnos correctamente, aunque todavía falta implementar funcionalidades como la ordenación o evitar que las celdas sean editables. Por ahora, la tabla solo sirve para visualizar los datos.

Este enfoque nos permite tener un control total sobre cómo se muestran y gestionan los datos en la interfaz, y sienta las bases para añadir más funcionalidades en futuras iteraciones.

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