Tras construir los modelos, debemos empezar a plantearnos los módulos de DAO. Estos módulos, son los encargados de mover la información desde la base de datos a los modelos, y necesitaremos un DAO para cada unos de los modelos….aunque nosotros, tanto para los modelos como para los DAOs hemos acudido a un pequeño generador que otro día explicare, pero que podéis encontrar en Github
La idea de los DAO
Un módulo dao, en nuestro planteamiento, ha de ser capaz de grabar un modelo en su tabla correspondiente, y/o actualizarlo o borrarlo, así como de leer uno, o una lista de objetos para devolverlos a la aplicación
En resumen, el dao se ha de responsabilizar de TODA la interacción necesaria entre el modelo y la base de datos.
Esas interacciones, deben contemplar como mínimo:
- Devolver un array con todos los registros ubicados en el objeto correspondientes (listAll()). con alternativa para obtener un JSON (listJson())
- Devolver ese array, seleccionando con una orden WHERE externa (listConWhere($where)). Con alternativa para obtener una salida JSON (listConWhereJson($where()
- Devolver un modelo de un registro seleccionado por medio de su PrimaryKey (listPorId($id)). Lanzara error, si no se encuentra el registro, o si se encuentra mas de uno.
- Actualizar en la base de datos, un objeto (modelo) recibido (update($model)). Se lanza excepción cuando SQL genere un error o cuando la orden afecte a más de un registro
- Insertar un nuevo registro en la tabla correspondiente, con los datos del modelo facilitado (inserta($modelo)). Se lanza excepción tanto si se recibe un error desde SQL, como si se afecta, por lo que sea, a más de un registro
- Borrar un registro de la base de datos, correspondiente al modelo que se le pasa(borra($modelo)). La orden se da por medio de la primary key que aparezca en el modelo pasado
Hay algunas opciones, que aunque se podrían ignorar, considero interesante disponer de ellas, por lo que las relaciono a continuación.
- Resetear el sistema de autoincremento al ultimo registro creado, util si deseas que el indice sea correlativo, aunque solo lo puedes utilizar en BBDD que dispongan de esa característica, o lo deberemos adaptar a la forma de trabajo prevista. El método se llama resetAutoincrement()
- Las órdenes correspondientes al inicio de transacción (beginTransaction()), final correcto de transaccion (commit()), retrocesión de la transacción (rollback()), todos ellos, lanzando excepciones si SQL nos informa del error
El desarrollo
Hemos dicho que cada modelo (tabla), deberá tener su propio DAO, pero, si analizamos el código que tenemos que escribir para cada uno de ellos, veremos que la estructura es terriblemente repetitiva, y la única diferencia que hay, será
- en la orden SQL que necesitamos para cada uno, ya que cambia el nombre de la tabla y el de cada campo
- el método que necesitamos para desmontar el objeto, ya que debemos hacer el get de cada campo, para el bind correspondiente
La solucion que he encontrado, es crear un módulo base con todo el código y tres métodos abstract para montar los datos necesarios para el update/insert y para el Delete, y de paso, para generar la SQL como string, que será cómodo cuando tengamos que imprimir la orden
Esos métodos se resuelven en el módulo que extienden, y que es uno por tabla, que, de paso, también facilita las constantes para realizar las distintas llamadas
- SELECT_ALL – Conseguir todos los registros
- SELECT_WHERE – Selecciona según criterio
- SELECT_UNO- seleccionar un registro, por id
- INSERTAR = insertar un registro
- ACTUALIZA – Actualizar un registro
- DELETE – borrar un registro por id
La clase base
A continuación, vemos el código de la clase base.
En la construcción, el nombre del modelo, del que podemos extraer el nombre de la tabla, y el nombre de la primary key
El método update, aprovecha el método montabind, resuelto en hijo, para terminar de montar la SQL de update, sacada también del hijo, luego, realiza la actualización, y si recibe algun error, utiliza el método (también del hijo) montaDebug, para conseguir una instrucción SQL con los valores devueltos, y mucho mas útil para visualizar en caso de errores.
El método insert es idéntico al anterior, utilizando la constante SQL de insertar
Y repetimos la estructura para borrar registros, escogiendo la sql que interesa, en este caso DELETE
Para leer registro por id, utilizamos la select correspondiente,(SELECT_UNO) aunque esta vez, esperamos que este esperando un atributo :id para igualarlo al campo de clave, de forma que el bind, lo podemos realizar aquí mismo.
Y como siempre, comprobamos que todo haya ido bien, para lanzar excepción en caso contrario
Los métodos que vienen a continuación se dedican a realizar select de conjuntos de registro, según comentamos anteriormente, y que no creo que os den ningun problema.
Todas ellas, se apoyan en funciones simples y que podéis encontrar en los fuentes del proyecto en github.
En el ultimo paquete, os muestro como he resuelto las funciones opcionales
que supongo no se alejan mucho de lo que esperabais.
Solo nos queda declarar los métodos que queremos se deban implementar en el hijo, para lo que utilizaremos la definición de abstract
Finalizando el DAO. Creación del hijo
Como hemos dicho, el base solo me proporciona los metodos comunes; para cada tabla a la que queramos acceder, necesitamos un modulo, que estendera del base y que aportara los datos que hemos dejado sin resolver .
Os adjunto un ejemplo (realizado con el generador del que os hable antes) y que si fuera necesario, podría añadir todos aquellos accesos que no son comunes a todas la tablas.
Esta sera la unica clase que se instancia para realizar funciones con la tabla, en este caso de Cp_comunidades
Tras esto, para poder probar el trabajo, bastaria con que crearamos un pequeño fichero index, con un poco de código, como este en cabecera:
y para probar algunas funciones, podríamos hacer, por ejemplo:
Ojo, que la línea 23 esta comentada, después de haber probado que funciona, por lo que vosotros primero habéis de probarla
Por último, añadimos las dos funciones que he estado utilizando y que son:
Un ultimo comentario. Mas adelante, montaremos las pruebas con PHPUnit, y las dejaremos organizadas, esto solo os ha de servir para calmar vuestra intranquilidad sobre lo codificado, y ver que todo funciona
Y la advertencia…Dado que voy desarrollando y escribiendo los comentarios, todo al mismo tiempo, he tenido que corregir algunas cosas del generador de modelos y dao y de DaoBase; os recuerdo que la ultima version…y espero que la correcta, siempre estara en Github, cada cosa en su repositorio:
Generador: https://github.com/recursosformacion/GeneradorMySQL2PHP
SDCA: https://github.com/recursosformacion/SDCA_PHP
Próximamente, empezaremos a resolver los controladores……
Relacionado
Descubre más desde Recursos para formacion
Suscríbete y recibe las últimas entradas en tu correo electrónico.