Los Objetos de Acceso a Datos (DAO) proveen una API genérica para acceder a los datos almacenados en diferentes sistemas de administraciond de bases de datos (DBMS). Como resultado, se puede cambiar de un DBMS a otro sin la necesidad de cambiar el código que usa DAO para acceder a los datos.
El DAO de Yii está construido sobre Objetos de Datos de PHP, que es una extensión que provee acceso unificado a datos a los DBMS más populares, como MySQL, PostgreSQL, etc. Por lo tanto, para usar el DAO de Yii, tienen que ser instaladas tanto la extensión PDO como el driver PDO de la base de datos (ej.: PDO_MYSQL).
El DAO de Yii principalmente consiste de las siguientes cuatro clases:
A continuación, mencionaremos el uso del DAO Yii en diferentes escenarios.
Para establecer la conexión con una base de datos, creamos una instancia de CDbConnetion y la activamos. Es necesario un nombre de fuente de datos (DNS) para especificar la información requerida para conectarse a la base de datos. Un nombre de usuario y contraseña pueden ser también necesarios para establecer la conexión. Será arrojada una excepción en el caso de que ocurra algún error al establecer la conexión (ej.: DNS malo o nombre de usuario/contraseña inválidos).
$connection=new CDbConnection($dsn,$username,$password);
// establish connection. You may try...catch possible exceptions
$connection->active=true;
......
$connection->active=false; // close connection
La forma del DNS depende del driver PDO de la base de datos en uso. En general, un DNS consiste del nombre del driver PDO, seguido por dos puntos (:), seguido por la sintaxis específica del driver. Mira la Documentación PDO para una información completa. A continuación, una lista de los formatos DNS más comunmente utilizados:
sqlite:/path/to/dbfile
mysql:host=localhost;dbname=testdb
pgsql:host=localhost;port=5432;dbname=testdb
Puesto que CDbConnetion extiende de CApplicationComponent, podemos también
usarla como un Componente de Aplicación.
Para hacerlo, configuramos un componente de aplicación db
(u otro nombre) en
Configuración de la Aplicación como sigue,
array(
......
'components'=>array(
......
'db'=>array(
'class'=>'CDbConnection',
'connectionString'=>'mysql:host=localhost;dbname=testdb',
'username'=>'root',
'password'=>'password',
),
),
)
Podemos entonces acceder a la conexión de la base de datos a través de
Yii::app()->db
(donde db
es el nombre que le pusimos al componente)
que ya está activada, a menos que explicitamente configuremos a
CDbConnection::autoConnect en false
. Usar este enfoque, una simple
conexión con la base de datos puede ser usada en diferentes lugares en
nuestro código.
Una vez establecida la conexión con la base de datos, las sentencias SQL pueden ser ejecutadas usando CDbCommand. Se crea una instancia CDbCommand llamando a CDbConnetion::createCommand() con la sentencia SQL especificada:
$command=$connection->createCommand($sql);
// if needed, the SQL statement may be updated as follows:
// $command->text=$newSQL;
Una sentencia SQL es ejecutada a través de CDbCommand en una de las siguientes dos maneras:
INSERT
, UPDATE
y DELETE
. Si es exitosa, devuelve el
numero de filas afectadas por la ejecución.SELECT
. Si es exitosa, develve una instancia de
CDbDataReader, a partid de la cual se recorrer el resultado de las filas
de datos. Por conveniencia, están implementados un conjunto de métodos
queryXXX()
, los cuales devuelven directamente el resultado de la consulta.Será arrojada una excepción si ocurre un error durante la ejecución de una sentencia SQL.
$rowCount=$command->execute(); // ejecuta una sentencia SQL sin resultados
$dataReader=$command->query(); // ejecuta una consulta SQL
$rows=$command->queryAll(); // consulta y devuelve todas las filas de resultado
$row=$command->queryRow(); // consulta y devuelve la primera fila de resultado
$column=$command->queryColumn(); // consulta y devuelve la primera columna de resultado
$value=$command->queryScalar(); // consulta y devuelve el primer campo en la primer fila
Luego de que CDbCommand::query() genere la instancia de CDbDataReader,
podemos recuperar filas del resultado llamando a CDbDataReader::read() de
manera repetida. Podemos tambien usar un CDbDataReader en un foreach
de PHP
para recuperar fila a fila.
$dataReader=$command->query();
// calling read() repeatedly until it returns false
while(($row=$dataReader->read())!==false) { ... }
// usando foreach para atravesar cada fila de datos
foreach($dataReader as $row) { ... }
// recuperando todos los datos de una vez en un único arreglo
$rows=$dataReader->readAll();
Nota: A diferencia de query(), todos los métodos
queryXXX()
devuelven datos directamente. Por ejemplo, queryRow() devuelve un arreglo representando la primera fila del resultado de la consulta.
Cuando una aplicación ejecuta unas pocas consultas, cada una leyendo y/o escribiendo información en la base de datos, es importante aseguarse que la base de datos no se quede sólo con algunas de las consultas llevadas a cabo. Para evitar esto, puede ser iniciada una transacción, representada en Yii como una instancia de CDbTransaction:
El anterior flujo de trabajo puede ser implementado usando el siguiente código:
$transaction=$connection->beginTransaction();
try
{
$connection->createCommand($sql1)->execute();
$connection->createCommand($sql2)->execute();
//.... other SQL executions
$transaction->commit();
}
catch(Exception $e) // se arroja una excepción si una consulta falla
{
$transaction->rollBack();
}
Para evitar ataques de SQL injection y para mejorar el rendimiento de sentencias SQL usadas repetidas veces, podemos "preparar" una sentencia SQL con marcadores de posición de parámetros opcionales, que son marcadores que serán reemplazados con los parámetros reales durante el proceso de vinculación de parámetros. El driver subyacente de la base de datos lo hará por nosotros. La vinculación de parámetros debe hacerse antes de que la sentencia SQL sea ejecutada.
// una SQL con dos marcadore de posición, ":username" and ":email"
$sql="INSERT INTO users(username, email) VALUES(:username,:email)";
$command=$connection->createCommand($sql);
// reemplaza el marcador de posición ":username" con el valor real de username
$command->bindParam(":username",$username,PDO::PARAM_STR);
// reemplaza el marcador de posición ":email" con el valor real de email
$command->bindParam(":email",$email,PDO::PARAM_STR);
$command->execute();
// inserta otra fila con un nuevo conjunto de parámetros
$command->bindParam(":username",$username2,PDO::PARAM_STR);
$command->bindParam(":email",$email2,PDO::PARAM_STR);
$command->execute();
Los métodos bindParam() y bindValue() son muy similares. La única diferencia es que el primero vincula un parámetro con una variable PHP mientras que el último con un valor. Para parámetros que representan grandes bloques de memoria de datos, es preferible el primero por consideraciones de rendimiento.
Para más detalles acerca de la vinculación de parámetros, mira la documentación PHP relevante.
Al recoger los datos del resultado de una consulta, podemos tambien vincular columnas con variables PHP para que sean automáticamente rellenadas con los datos apropiados cada vez que una fila es recogida.
$sql="SELECT username, email FROM users";
$dataReader=$connection->createCommand($sql)->query();
// vincular la 1er columna (username) con la variable $username
$dataReader->bindColumn(1,$username);
// vincular la 2da columna (email) con la variable $email
$dataReader->bindColumn(2,$email);
while($dataReader->read()!==false)
{
// $username e $email contienen el nombre de usuaario y el email de la fila actual
}
Signup or Login in order to comment.