Introducción.
- Los objetos de acceso a datos (DAO) permiten el acceso genérico a las bases de datos, permitiendo cambiar el motor de base de datos sin impactar el sistema.
- Se basan en PHP Data Objects (PDO) por lo cual la instalación de PHP deberá tener presentes los módulos correspondientes.
- Se incluye el soporte para los siguientes motores de base de datos.
- La arquitectura se compone por cuatro clases.
- CDbConnection: conexión a la base de datos.
- CDbCommand: sentencias para ser ejecutadas en la base de datos.
- CDbDataReader: lector unidireccional y de sólo lectura para resultados de consultas.
- CDbTransaction: transacciones de la base de datos.
Establecer la conexión.
De manera explícita.
- Se basa en la creación de un objeto CDbConnection, la especificación de un Data Source Name (DSN) y la información de autenticación del usuario de conexión si es necesaria.
$conexion = CDbConnection($DSN, $username, $password); $conexion -> active = true; // Abrir la conexión, se lanzan excepciones en error. // ... $conexion -> active = false; // Cerrar la conexión.
- El formato del DSN depende del módulo de PDO utilizado.
- SQLite: sqlite:/ruta/al/archivo/sqlite
- MySQL: mysql:host=<HOST>;dbname=<NAME>
- PostgreSQL: pgsql:host=<HOST>;port=<PORT [5432]>;dbname=<NAME>
- MSSQL: mssql:host=<HOST>;dbname=<NAME>
- Oracle: oci:dbname=//<HOST>:<PORT [1521]>/<NAME>
De manera automática.
- La clase CDbConnection es un CApplicationComponent por lo que puede ser configurado como un componente de aplicación.
- Para hacer esto es necesario modificar la configuración de la aplicación (protected/config/main.php) de la siguiente manera para agregar al componente db.
array ( // ... 'components' => array ( 'db' => array ( 'class' => 'CDbConnection', 'connectionString' => 'mysql:host=database.server.com;dbname=demo_db', 'username' => 'demo_user', 'password' => 'demo_pass' ) ) );
- De esta manera la conexión se realiza de manera automática y puede accederse mediante Yii::app() -> db.
Ejecutar sentencias.
- Es necesario crear un CDbCommand a través de CDbConnection::createCommand().
$comando = $conexion -> createCommand($sql); // $comando -> text = $nuevoSQL; // Actualiza el SQL de un comando
- La sentencia puede ejecutarse de dos maneras.
- execute() para sentencias de modificación como INSERT, UPDATE y DELETE. En éxito retorna el número de registros afectados.
- query() para sentencias de consulta (SELECT). En éxito retorna un CDbDataReader.
- Existen otros métodos mas específicos del estilo queryXXX() que facilitan la obtención de los resultados.
- $filas = $comando -> queryAll(). Consulta y retorna inmediatamente todas las filas del resultado.
- $fila = $comando -> queryRow(). Consulta y retorna inmediatamente la primera fila del resultado.
- $columna = $comando -> queryColumn(). Consulta y retorna inmediatamente la primera columna del resultado.
- $valor = $comando -> queryScalar(). Consulta y retorna inmediatamente el valor de la primera fila y primera columna del resultado.
Obtener los resultados.
- Si se utilizó un método del estilo queryXXX() el valor obtenido como resultado es retornado inmediatamente.
- Si se utilizó el método query(), los resultados pueden obtenerse de tres maneras.
- Mediante múltiples llamados a CDataReader::read().
$dataReader = $comando -> query(); while(($fila = $dataReader -> read()) !== false) { // ... }
- Mediante la construcción foreach la cual extrae una fila por cada iteración.
foreach($dataReader as $fila) { // ... }
- Obtiene inmediatamente un arreglo con todas las filas del resultado.
$filas = $dataReader -> readAll();
- Mediante múltiples llamados a CDataReader::read().
Utilizar transacciones.
- Se basan en la manipulación de un objeto de clase CDbTransaction.
$transaccion = $conexion -> beginTransaction(); // Inicio de la transacción. try { $conexion -> createCommand($sql) -> execute(); // Ejecuta las sentencias SQL. // ... $transaccion -> commit(); // Almacena los cambios realizados en los datos. } catch(Exception $e) // Captura cualquier excepción sucedida. { $transaccion -> rollBack(); // En error se cancela la transacción y deshacen sus cambios. }
Parametrizar consultas.
- Son útiles para evitar la inyección de SQL y para aumentar el rendimiento en la ejecución de consultas recurrentes.
- Se basa en la ubicación de marcas en el código SQL que después son reemplazadas por valores dinámicamente.
- Las marcas pueden tener un nombre (etiquetas únicas como :nombre y :contrasena) o ser anónimas (representadas por ?).
- Para reemplazar las marcas por los valores finales pueden utilizarse los siguientes métodos.
- CDbCommand::bindParam(). Relaciona la marca con una referencia a la variable PHP. Para valores grandes esta opción es preferible en términos de desempeño.
- CDbCommand::bindValue(). Relaciona la marca con el valor de una varible PHP.
- El reemplazo de las marcas debe hacerse antes de que la consulta sea ejecutada.
$sql = "INSERT INTO usuario(nombre, contrasena) VALUES(:username, :password)"; $comando = $conexion -> createCommand($sql); // Agregar el primer usuario. $comando -> bindParam(":username", $nombre1, PDO::PARAM_STR); $comando -> bindParam(":password", $contrasena1, PDO::PARAM_STR); $comando -> execute(); // Agregar el segundo usuario. $comando -> bindParam(":username", $nombre2, PDO::PARAM_STR); $comando -> bindParam(":password", $contrasena2, PDO::PARAM_STR); $comando -> execute(); // ...
Las constantes que determinan el tipo del valor a reemplazarse por la marca pueden consultarse en la sección de Constantes Predefinidas de PDO en el manual de PHP.
Asociar columnas.
- Yii provee una facilidad adicional para la manipulación de resultados provenientes de la base de datos.
- Consiste en relacionar variables con las columnas del resultado así se actualizarán de manera automática en cada iteración que obtenga una nueva fila de datos.
$sql = "SELECT nombre, contrasena FROM usuario"; $dataReader = $conexion -> createCommand($sql) -> query(); // Asociar las variables $username y $password a las columnas uno y dos del resultado. $dataReader -> bindColumn(1, $username); $dataReader -> bindColumn(2, $password); while($dataReader -> read() !== false) { // $username y $password tendrán el valor de cada fila // del resultado en cada una de las iteraciones. }
Enlaces.
- Yii Web Programming Framework.
http://www.yiiframework.com/ - Yii Documentation.
http://www.yiiframework.com/doc/
One Reply to “Data Access Objects (DAO) con Yii”