Ejemplo: Crear los DAO (parte 1)

Los DAO son las clases que acceden a la base de datos para cargar y guardar los modelos de nuestra aplicación. En esta primera parte creo la estructura de los DAO y en el siguiente vídeo relleno el código.

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

Cuando trabajamos con bases de datos en Java, una práctica muy recomendable es centralizar toda la lógica de acceso a datos en objetos específicos llamados DAO (Data Access Object). Estos objetos se encargan de manejar la conexión con la base de datos y realizar las operaciones básicas de inserción, consulta, actualización y eliminación, conocidas como CRUD, para cada uno de los modelos que tengamos en nuestra aplicación.

Imaginemos que tenemos varias entidades como alumno, asignatura, matrícula y profesor. Para cada una de ellas crearemos un DAO dedicado: alumno DAO, asignatura DAO, matrícula DAO y profesor DAO. Esta organización nos permite mantener el código limpio y separado, evitando que las consultas SQL estén dispersas por toda la aplicación. Además, al usar JDBC, el patrón DAO resulta especialmente cómodo y sencillo de implementar en Java.

Para estructurar mejor nuestro código, lo ideal es definir primero una interfaz genérica DAO que contenga los métodos comunes a todos los DAOs, como insertar, obtener por ID, listar todos, modificar y eliminar. Esta interfaz puede usar plantillas genéricas para que funcione con cualquier tipo de entidad y con cualquier tipo de clave primaria. Por ejemplo, podemos definirla con dos parámetros genéricos: T para la clase de la entidad y K para el tipo de la clave primaria, que en nuestro caso suele ser un long.

public interface DAO<T, K> {
    void insertar(T entidad);
    T obtenerPorId(K id);
    List<T> listarTodos();
    void modificar(T entidad);
    void eliminar(K id);
}

A partir de esta interfaz base, creamos interfaces específicas para cada entidad, que simplemente extienden la interfaz genérica con los tipos concretos. Por ejemplo, el AlumnoDAO extiende DAO<Alumno, Long>, el AsignaturaDAO extiende DAO<Asignatura, Long>, y así sucesivamente. Esto nos ahorra repetir código y mantiene la coherencia en las operaciones que cada DAO debe implementar.

Luego, para cada DAO definimos una implementación concreta, por ejemplo para MySQL, que implementa la interfaz correspondiente y contiene el código SQL necesario para realizar cada operación. Así, tendremos clases como MySQLAlumnoDAO, MySQLAsignaturaDAO, MySQLMatriculaDAO y MySQLProfesorDAO. Cada una de estas clases implementará los métodos de la interfaz y ejecutará las consultas SQL específicas para insertar, obtener, modificar o eliminar registros en la base de datos.

Un aspecto importante a considerar es cómo manejar las relaciones entre entidades, especialmente las claves foráneas. En nuestro diseño hemos optado por representar estas relaciones usando identificadores simples de tipo Long en lugar de objetos completos. Por ejemplo, una matrícula tendrá un campo long que representa el ID del profesor o de la asignatura relacionada.

Esta decisión tiene ventajas y desventajas. Usar identificadores numéricos hace que cada DAO sea independiente y evita que tengamos que cargar objetos relacionados automáticamente, lo que puede complicar el diseño y generar dependencias circulares entre DAOs. Por otro lado, si representamos las relaciones con objetos completos, tendríamos que hacer que un DAO utilice a otro para cargar los datos relacionados, lo que puede ser más intuitivo pero también más complejo de gestionar.

Al final, la elección depende de si queremos que nuestro modelo cargue automáticamente los objetos relacionados o si preferimos manejar esa carga de forma explícita en la aplicación. En cualquier caso, cuando usamos identificadores, tendremos que consultar el DAO correspondiente para obtener los datos completos del objeto relacionado cuando los necesitemos.

Este tipo de gestión de relaciones es precisamente lo que facilitan los ORM (Object-Relational Mapping), que nos permiten trabajar con objetos completos y cargan las relaciones de forma automática o bajo demanda, evitando que tengamos que escribir manualmente todo el código SQL y la lógica de carga de objetos relacionados.

Sin embargo, si preferimos controlar todo a mano y entender bien cómo funciona el acceso a datos, implementar nuestros propios DAOs con JDBC y manejar las relaciones mediante identificadores es una forma clara y didáctica de hacerlo.

En la siguiente etapa, nos centraremos en escribir el código SQL para cada uno de los métodos de los DAOs y en cómo conectar estas implementaciones con la base de datos MySQL para que nuestra aplicación pueda interactuar con los datos de forma efectiva.

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