Data Access Objects (DAO) con Yii

Introducción.

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.
    1. SQLite: sqlite:/ruta/al/archivo/sqlite
    2. MySQL: mysql:host=<HOST>;dbname=<NAME>
    3. PostgreSQL: pgsql:host=<HOST>;port=<PORT [5432]>;dbname=<NAME>
    4. MSSQL: mssql:host=<HOST>;dbname=<NAME>
    5. 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.
    1. execute() para sentencias de modificación como INSERT, UPDATE y DELETE.  En éxito retorna el número de registros afectados.
    2. 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.
    1. $filas = $comando -> queryAll().   Consulta y retorna inmediatamente todas las filas del resultado.
    2. $fila = $comando -> queryRow().   Consulta y retorna inmediatamente la primera fila del resultado.
    3. $columna = $comando -> queryColumn().   Consulta y retorna inmediatamente la primera columna del resultado.
    4. $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.
    1. Mediante múltiples llamados a CDataReader::read().
      $dataReader = $comando -> query();
      while(($fila = $dataReader -> read()) !== false)
      {
          // ...
      }
    2. Mediante la construcción foreach la cual extrae una fila por cada iteración.
      foreach($dataReader as $fila)
      {
          // ...
      }
    3. Obtiene inmediatamente un arreglo con todas las filas del resultado.
      $filas = $dataReader -> readAll();

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.
    1. 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.
    2. 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.

One thought on “Data Access Objects (DAO) con Yii”

Leave a Reply

Your email address will not be published. Required fields are marked *