Data Access Objects (DAO)

Data Access Objects (DAO, Objetos de Acesso a Dados), fornecem uma API genérica para acessar dados em diferentes tipos de bancos de dados. Como resultado, pode-se alterar o sistema de banco de dados sem haver a necessidade de alterar o código que utiliza DAO para fazer o acesso.

O DAO do Yii é feito utilizando a extensão PHP Data Objects (PDO), que fornece um acesso de dados unificado para muitos SGBD populares, tais como MySQL e PostgreSQL. Por esse motivo, para utilizar o DAO no Yii, a extensão PDO deve estar instalada, bem como o driver PDO específico para o banco de dados utilizado (por exemplo, PDO_MYSQL).

O DAO no Yii, consiste, basicamente, das quatro classes seguinte:

A seguir, apresentaremos a utilização do DAO no Yii em diferente cenários.

Estabelecendo uma Conexão com o Banco de Dados

Para estabelecer uma conexão com o banco de dados, criamos uma instância de CDbConnection e a ativamos. É necessário o nome da fonte de dados (data source name, DSN) para conectar-se ao banco. Também podem ser necessários o nome de usuário e senha para o acesso. Uma exceção será disparada caso ocorra um erro ao estabelecer a conexão (por exemplo, um DSN incorreto, ou usuário/senha inválidos).



O formato do DSN depende do driver PDO em uso. Geralmente, o DSN é formado pelo nome do driver PDO, seguido por ":", seguido pela sintaxe de conexão específica do driver. Veja PDO documentation para mais informações. Abaixo temos uma lista dos formatos de DSN mais utilizados:

Como a classe CDbConnection estende a classe CApplicationComponent, podemos utiliza-la como um componente da aplicação. Para isso, configure um componente chamado db (ou qualquer outro nome) na configuração da aplicação, como no código a seguir:



Podemos então acessar a conexão com o banco via Yii::app()->db, que é ativada automaticamente, a não ser que se configure a propriedade CDbConnection::autoConnect para false. Dessa maneira, uma única conexão com o banco de dados pode ser compartilhada entre diversas partes de seu código.

Executando Instruções SQL

Uma vez que a conexão com o banco de dados tenha sido estabelecida, comandos SQL podem ser executados utilizando-se a classe CDbCommand. Você pode criar uma instância de CDbCommand utilizando o método CDbConnection::createCommand(), com a instrução SQL desejada:



Uma instrução SQL pode ser executada via CDbCommand de duas maneiras:

Uma exceção será disparada caso ocorram erros durante a execução de instruções SQL.



Obtendo Resultados de Consultas

Depois que o método CDbCommand::query() gerar uma instância de CDbDataReader, você pode recuperar os registros do resultado através do método CDbDataReader::read(), repetidamente. Você também pode utilizar um CDbDataReader dentro de um loop foreach, para recuperar os registros, um a um:



Nota: Diferente do método query(), todos os métodos queryXXX(), retornam os dados diretamente. Por exemplo, o método queryRow() retorna um vetor representando o primeiro registro do resultado da consulta.

Utilizando Transações (Transactions)

Quando uma aplicação executa algumas consultas, seja lendo ou gravando informações no banco de dados, é importante garantir que todas as consultas tenham sido executadas. Nesse caso, uma transação, representada por uma instância de CDbTransaction, pode ser iniciada:

O fluxo acima pode ser implementado como no código a seguir:



Vinculando (Binding) Parâmetros

Para evitar ataques de SQL injection e aumentar a performance ao executar instruções SQL repetidamente, você pode "preparar" um comando SQL com marcadores opcionais que serão substituídos pelos valores reais, durante o processo de vinculação de parâmetros.

Os marcadores de parâmetros podem ser nomeados (representados por tokens únicos) ou anônimos (representados por interrogações). Execute o método CDbCommand::bindParam() ou CDbCommand::bindValue() para substituir esses marcadores pelos parâmetros reais. Eles não precisam estar entre aspas: o próprio driver do banco de dados faz isso para você. A vinculação de parâmetros deve ser realizada antes da instrução SQL ser executada.



Os métodos bindParam() e bindValue() são similares. A única diferença entre eles é que o primeiro vincula um parâmetro utilizando uma referência para a variável enquanto o outro utilizar um valor. Para parâmetros que representem uma grande quantidade de dados em memória, o primeiro é mais recomendado, devido a uma melhor performance.

Para mais detalhes sobre a vinculação de parâmetros, veja a documentação do PHP.

Vinculando Colunas

Ao recuperar os resultados de uma consulta, você também pode vincular colunas à variáveis, de forma que elas sejam automaticamente preenchidas cada vez que um novo registro é recuperado:



Utilizando Prefixos de Tabelas

A partir da versão 1.1.0, o Yii framework possui suporte integrado para a utilização de prefixos em nomes de tabela. Um prefixo é uma string que será anexada ao início dos nomes das tabelas do banco de dados conectado. Normalmente, eles são utilizados em ambientes de hospedagem compartilhada, onde múltiplas aplicações utilizam um único banco de dados e é necessário diferenciar as tabelas de cada aplicação. Por exemplo, uma aplicação pode utilizar o prefixo tbl_, enquanto outra utiliza yii_.

Para utiliza-los, você deverá configurar a propriedade CDbConnection::tablePrefix com o prefixo desejado. Feito isso, em suas consultas SQL você deverá utilizar {{NomeDaTabela}}, onde NomeDaTabela é o nome da tabela sem o prefixo. Por exemplo, se um banco de dados contém uma tabela chamada tbl_user e tbl_ é o prefixo configurado, então você pode utilizar o seguinte código para realizar consultas nessa tabela:



$Id: database.dao.txt 2266 2010-07-17 13:58:30Z qiang.xue $