Alexander Makarov
10 years ago
2 changed files with 294 additions and 1 deletions
@ -0,0 +1,293 @@
|
||||
Trabalhando com Bancos de Dados |
||||
=============================== |
||||
|
||||
Esta seção descreverá como criar uma nova página que exibe dados de países |
||||
buscados de uma tabela do banco de dados chamada `country`. Para isso, você |
||||
configurará uma conexão com o banco de dados, criará uma classe de |
||||
[Active Record](db-active-record.md), definirá uma [action](structure-controllers.md) (ação), |
||||
e criará uma [view](structure-views.md) (visão). |
||||
|
||||
Através deste tutorial, você aprenderá como: |
||||
|
||||
* Configurar uma conexão de BD |
||||
* Definir uma classe de Active Record |
||||
* Consultar dados usando a classe de Active Record |
||||
* Exibir dados em uma view de modo paginado |
||||
|
||||
Perceba que para terminar essa seção, você deve ter conhecimento e experiência |
||||
básica usando bancos de dados. Em particular, você deveria saber como criar um |
||||
banco de dados, e como executar declarações SQL usando uma ferramente de cliente |
||||
de BD. |
||||
|
||||
|
||||
Preparando o Banco de Dados <a name="preparing-database"></a> |
||||
--------------------------- |
||||
|
||||
Para começar, crie um banco de dados chamado `yii2basic`, a partir do qual você |
||||
buscará os dados em sua aplicação. Você pode criar um banco de dados SQLite, MySQL, |
||||
PostgreSQL, MSSQL ou Oracle, já que o Yii tem suporte embutido a muitas aplicações |
||||
de bancos de dados. Por questões de simplicidade, será assumido o uso do MySQL |
||||
na descrição a seguir. |
||||
|
||||
Em seguida, crie uma tabela chamada `country` no banco de dados, e insira alguns |
||||
dados de exemplo. Você pode rodar as seguintes declarações SQL para fazê-lo: |
||||
|
||||
```sql |
||||
CREATE TABLE `country` ( |
||||
`code` CHAR(2) NOT NULL PRIMARY KEY, |
||||
`name` CHAR(52) NOT NULL, |
||||
`population` INT(11) NOT NULL DEFAULT '0' |
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
||||
|
||||
INSERT INTO `country` VALUES ('AU','Australia',18886000); |
||||
INSERT INTO `country` VALUES ('BR','Brazil',170115000); |
||||
INSERT INTO `country` VALUES ('CA','Canada',1147000); |
||||
INSERT INTO `country` VALUES ('CN','China',1277558000); |
||||
INSERT INTO `country` VALUES ('DE','Germany',82164700); |
||||
INSERT INTO `country` VALUES ('FR','France',59225700); |
||||
INSERT INTO `country` VALUES ('GB','United Kingdom',59623400); |
||||
INSERT INTO `country` VALUES ('IN','India',1013662000); |
||||
INSERT INTO `country` VALUES ('RU','Russia',146934000); |
||||
INSERT INTO `country` VALUES ('US','United States',278357000); |
||||
``` |
||||
|
||||
Neste ponto, você tem um banco de dados chamado `yii2basic`, e dentro dele uma |
||||
tabela `country` com três colunas, contendo dez linhas de dados. |
||||
|
||||
Configurando uma Conexão do BD <a name="configuring-db-connection"></a> |
||||
------------------------------ |
||||
|
||||
Antes de prosseguir, certifique-se de que você possui instalados tanto a |
||||
extensão [PDO](http://www.php.net/manual/en/book.pdo.php) do PHP quanto o driver |
||||
do PDO para a base que você está usando (por exemplo, `pdo_mysql` para o MySQL). |
||||
Este é um requisito básico se a sua aplicação usa um banco de dados relacional. |
||||
|
||||
Tendo estes instalados, abra o arquivo `config/db.php` e mude os parâmetros para |
||||
que estejam corretos para o seu banco de dados. Por padrão, o arquivo contém |
||||
o seguinte: |
||||
|
||||
```php |
||||
<?php |
||||
|
||||
return [ |
||||
'class' => 'yii\db\Connection', |
||||
'dsn' => 'mysql:host=localhost;dbname=yii2basic', |
||||
'username' => 'root', |
||||
'password' => '', |
||||
'charset' => 'utf8', |
||||
]; |
||||
``` |
||||
|
||||
O arquivo `config/db.php` é uma ferramenta de [configuração](concept-configurations.md) |
||||
típica baseada em arquivos. Este arquivo de configuração em particular especifica |
||||
os parâmetros necessários para criar e inicializar uma instância de [[yii\db\Connection]] |
||||
através da qual você pode fazer consultas de SQL ao banco de dados subjacente. |
||||
|
||||
A conexão de BD configurada acima pode ser acessada no código da aplicação |
||||
através da expressão `Yii::$app->db`. |
||||
|
||||
> Info: O arquivo `config/db.php` será incluso pela configuração principal da |
||||
aplicação `config/web.php`, que especifica como a instância da [aplicação](structure-applications.md) |
||||
deverá ser inicializada. Para mais informações, por favor consulte a seção sobre [Configurações](concept-configurations.md). |
||||
|
||||
|
||||
Criando um Active Record <a name="creating-active-record"></a> |
||||
------------------------ |
||||
|
||||
Para representar e buscar os dados da tabela `country`, crie uma classe que |
||||
deriva de [Active Record](db-active-record.md) chamada `Country`, e salve-a |
||||
no arquivo `models/Country.php`. |
||||
|
||||
```php |
||||
<?php |
||||
|
||||
namespace app\models; |
||||
|
||||
use yii\db\ActiveRecord; |
||||
|
||||
class Country extends ActiveRecord |
||||
{ |
||||
} |
||||
``` |
||||
|
||||
A classe `Country` estende de [[yii\db\ActiveRecord]]. Você não precisa escrever |
||||
nenhum código nela! Só com o código acima, o Yii adivinhará o nome da tabela |
||||
associada a partir do nome da classe. |
||||
|
||||
> Info: Se não houver nenhuma correspondência direta do nome da classe com o nome |
||||
da tabela, você pode sobrescrever o método [[yii\db\ActiveRecord::tableName()]] |
||||
para especificar explicitamente o nome da tabela associada. |
||||
|
||||
Usando a classe `Country`, você pode manipular facilmente os dados na tabela |
||||
`country`, conforme é demonstrado nestes fragmentos: |
||||
|
||||
```php |
||||
use app\models\Country; |
||||
|
||||
// obtém todas as linhas da tabela country e as ordena pela coluna "name" |
||||
$countries = Country::find()->orderBy('name')->all(); |
||||
|
||||
// obtém a linha cuja chave primária é "US" |
||||
$country = Country::findOne('US'); |
||||
|
||||
// exibe "United States" |
||||
echo $country->name; |
||||
|
||||
// altera o nome do país para ser "U.S.A." e o salva no banco de dados |
||||
$country->name = 'U.S.A.'; |
||||
$country->save(); |
||||
``` |
||||
|
||||
> Info: O Active Record é uma maneira poderosa de acessar e manipular os dados |
||||
do banco de dados de um modo orientado a objeto. Você pode encontrar informações |
||||
mais detalhadas na seção [Active Record](db-active-record.md). Alternativamente, |
||||
você também pode interagir com o banco de dados usando um método de acesso aos |
||||
dados de baixo nível chamado [Data Access Objects](db-dao.md). |
||||
|
||||
|
||||
Criando uma Action <a name="creating-action"></a> |
||||
------------------ |
||||
|
||||
Para expor os dados de países aos usuários finais, você precisaria de uma nova |
||||
action. Ao invés de colocar a nova action no controller (controlador) `site`, |
||||
como você fez nas seções anteriores, faz mais sentido criar um novo controller |
||||
especificamente para todas as actions relacionadas aos dados de países. Chame |
||||
este novo controller de `CountryController`, e crie uma action `index` nele, |
||||
conforme o exemplo a seguir. |
||||
|
||||
```php |
||||
<?php |
||||
|
||||
namespace app\controllers; |
||||
|
||||
use yii\web\Controller; |
||||
use yii\data\Pagination; |
||||
use app\models\Country; |
||||
|
||||
class CountryController extends Controller |
||||
{ |
||||
public function actionIndex() |
||||
{ |
||||
$query = Country::find(); |
||||
|
||||
$pagination = new Pagination([ |
||||
'defaultPageSize' => 5, |
||||
'totalCount' => $query->count(), |
||||
]); |
||||
|
||||
$countries = $query->orderBy('name') |
||||
->offset($pagination->offset) |
||||
->limit($pagination->limit) |
||||
->all(); |
||||
|
||||
return $this->render('index', [ |
||||
'countries' => $countries, |
||||
'pagination' => $pagination, |
||||
]); |
||||
} |
||||
} |
||||
``` |
||||
|
||||
Salve o código acima em um arquivo `controllers/CountryController.php`. |
||||
|
||||
A action `index` chama `Country::find()`. Este método do Active Record constrói |
||||
uma consulta do BD e retorna todos os dados da tabela `country`. Para limitar o |
||||
número de países retornados em cada requisição, a consulta é paginada com a ajuda |
||||
de um objeto [[yii\data\Pagination]]. O objeto `Pagination` serve para dois propósitos: |
||||
|
||||
* Definir as cláusulas `offset` e `limit` da declaração SQL representada pela |
||||
consulta de modo que apenas retorne uma única página de dados por vez (no máximo |
||||
5 linhas por página). |
||||
* É usado para que a view exiba um paginador que consite de uma lista de botões |
||||
para as páginas, conforme será explicado na próxima sub-seção. |
||||
|
||||
No final do código, a action `index` renderiza uma view chamada `index`, e passa |
||||
para ela os dados dos países bem como as informações de paginação. |
||||
|
||||
|
||||
Criando uma View <a name="creating-view"></a> |
||||
---------------- |
||||
|
||||
Dentro do diretório `views`, primeiro crie um sub-diretório chamado `country`. |
||||
Esta pasta será usada para guardar todas as views renderizadas pelo controller |
||||
`country`. Dentro do diretório `views/country`, crie um arquivo `index.php` |
||||
contendo o seguinte: |
||||
|
||||
```php |
||||
<?php |
||||
use yii\helpers\Html; |
||||
use yii\widgets\LinkPager; |
||||
?> |
||||
<h1>Countries</h1> |
||||
<ul> |
||||
<?php foreach ($countries as $country): ?> |
||||
<li> |
||||
<?= Html::encode("{$country->name} ({$country->code})") ?>: |
||||
<?= $country->population ?> |
||||
</li> |
||||
<?php endforeach; ?> |
||||
</ul> |
||||
|
||||
<?= LinkPager::widget(['pagination' => $pagination]) ?> |
||||
``` |
||||
|
||||
A view tem duas seções relativas à exibição dos dados dos países. Na primeira parte, |
||||
os dados de países fornecidos são cruzados e renderizados como uma lista do HTML. |
||||
Na segunda parte, um widget [[yii\widgets\LinkPager]] é renderizado usando as |
||||
informações de paginação passadas pela action. O widget `LinkPager` exibe uma |
||||
lista de botões para as páginas. Ao clicar em qualquer um deles atualizará |
||||
os dados dos países com a página correspondente. |
||||
|
||||
|
||||
Testando <a name="trying-it-out"></a> |
||||
-------- |
||||
|
||||
Para verificar se todo o código acima funciona, use o seu navegador para |
||||
acessar a seguinte URL: |
||||
|
||||
``` |
||||
http://hostname/index.php?r=country/index |
||||
``` |
||||
|
||||
![Lista de Países](images/start-country-list.png) |
||||
|
||||
Primeiramente, você verá uma lista exibindo cinco países. Abaixo dos países, |
||||
você verá um paginador com quatro botões. Se você clicar no botão "2", você |
||||
verá a página exibindo outros cinco países no banco de dados: a segunda |
||||
página de registros. Observe mais cuidadosamente e você perceberá que a URL no |
||||
browser mudou para |
||||
|
||||
``` |
||||
http://hostname/index.php?r=country/index&page=2 |
||||
``` |
||||
|
||||
Por baixo dos panos, [[yii\data\Pagination|Pagination]] está fornecendo toda |
||||
a funcionalidade necessária para paginar um conjunto de dados: |
||||
|
||||
* Inicialmente, [[yii\data\Pagination|Pagination]] representa a primeira página, |
||||
que reflete a consulta SELECT de países com a cláusula `LIMIT 5 OFFSET 0`. |
||||
Como resultado, os primeiros cinco países serão buscados e exibidos. |
||||
* O widget [[yii\widgets\LinkPager|LinkPager]] renderiza os botões das páginas |
||||
usando as URLs criadas pelo [[yii\data\Pagination::createUrl()|Pagination]]. |
||||
As URLs conterão um parâmetro `page`, que representa os diferentes números de |
||||
páginas. |
||||
* Se você clicar no botão da página "2", uma nova requisição para a rota |
||||
`country/index` será disparada e tratada. [[yii\data\Pagination|Pagination]] lê |
||||
o parâmetro `page` da URL e define o número da página atual como sendo 2. A nova |
||||
consulta de países então terá a cláusula `LIMIT 5 OFFSET 5` e retornará os |
||||
próximos cinco países para a exibição. |
||||
|
||||
|
||||
Resumo <a name="summary"></a> |
||||
------ |
||||
|
||||
Nesta seção, você aprendeu como trabalhar com um banco de dados. Você também |
||||
aprendeu como buscar e exibir dados em páginas com a ajuda do |
||||
[[yii\data\Pagination]] e do [[yii\widgets\LinkPager]]. |
||||
|
||||
Na próxima seção, você aprenderá como usar a poderosa ferramenta geradora de códigos, |
||||
chamada [Gii](tool-gii.md), para ajudá-lo a implementar rapidamente algumas |
||||
funcionalidades comumente necessárias, tais como as operações CRUD |
||||
(Criar-Ler-Atualizar-Excluir) para trabalhar com os dados em uma tabela do |
||||
banco de dados. Na verdade, todo o código que você acabou de escrever pode ser |
||||
gerado automaticamente no Yii usando a ferramenta Gii. |
Loading…
Reference in new issue