Continuando o tópico Entendendo modelos no zend framework, que fizemos uma introdução sobre o uso de modelos, vamos falar agora sobre o mapeamento de relacionamentos das tabelas do banco de dados nos modelos baseados na classe Zend_Db_Table.
Banco de dados relacional
Um banco de dados relacional é um conjunto de tabelas relacionadas entre si gerenciadas por um SGBD (Sistema Gerenciador de Banco de Dados), que utiliza, por padrão, a linguagem SQL (Structured Query Language – linguagem de Consulta estruturada). Além de possibilitar a criação de tabelas, em um banco de dados relacional é possível criar relacionamentos entre as tabelas, o que garante a integridade dos dados que essas irão receber.
Tipos de relacionamentos de um banco de dados relacional
- 1 para 1 – Este tipo de relacionamento se dá, de forma direta entre duas tabelas, quando a chave primária do registro de uma determinada tabela pode ser utilizada uma única vez em um dos registros da outra tabela.
- 1 para N – Também acontece de forma direta entre duas tabelas sempre que a chave primária do registro de uma determinada tabela é utilizada várias vezes em outra tabela, sendo este, o tipo de relacionamento mais comum entre tabelas de um banco de dados relacional.
- N para N – Esse tipo de relacionamento que acontece de forma indireta entre duas tabelas, pois para que ele possa ser concebido é necessário a geração de uma terceira tabela. Na prática o relacionamento vários para vários não existe de fato, o que existe são dois ou mais relacionamentos um para vários, que ganha o sentido de vários para vários. Ocorre sempre que surge a necessidade de se relacionar duas chaves primárias de registros de diferentes tabelas em vários registros de uma terceira tabela.
Mapeamento usando Zend_Db_Table
Para que os relacionamentos funcionem nos modelos baseados na classe Zend_Db_Table, basta informar quais modelos são dependentes e quais os modelos são referênciados, ou seja, indicamos quais modelos dependem do modelo que está sendo mapeado e quais modelos são necessários para ele.
Tipos de mapeamentos usando Zend_Db_Table
- $_dependentTables – Responsável por mapear os modelos dependentes, sendo necessário informar o nome de cada modelo dependente.
- $_referenceMap – Responsável pelo mapeamento dos modelos referênciados, nele informamos as colunas equivalentes e o nome do modelo necessário.
Confira mais sobre mapeamento na documentação sobre relacionamentos com Zend_Db_Table.
Projeto usando relacionamento nos modelos
Agora que vimos um pouco sobre banco de dados relacional e mapeamento usando Zend_Db_Table, vamos criar um projeto para trabalhar com relacionamentos, baseado na estrutura apresentada no tópico Preparando o ambiente para desenvolvimento com Zend Framework, crie um projeto com nome de example-relationship.
No exemplo que será visto agora, iremos colocar em prática os dois tipos de mapeamento para que o relacionamento entre as tabelas aconteça, confira o diagrama do nosso banco de dados:
Detalhando o diagrama:
- Usuário cadastra vários produtos / Produto é cadastrado por um usuário
- Usuário faz vários pedidos / Pedido é realizado por um usuário
- Pedido possui vários itens / Item pertence a um pedido
- Item tem um produto / Produto pode estar em vários itens
Obs: Na prática um relacionamento N para N não existe, no diagrama acima representamos o relacionamento N para N usando dois relacionamentos 1 para N, o relacionamento Order – Product é um relacionamento N para N, um produto pode estar em vários pedidos e um pedido pode ter vários produtos, para isso criamos a tabela order_item, que fica responsável por esse relacionamento, armazenando as chaves primárias das tabelas Order e Product, como vimos no diagrama, esse tipo de tabela também pode ter colunas extras, no caso adicionamos uma coluna para guardar a quantidade de cada item do pedido.
Visualize ou efetue o download do script sql, no script além dos comandos de criação das tabelas, contém comandos para inserir valores nas tabelas para que o exemplo no final do artigo funcione corretamente.
Acesse o phpmyadmin, crie o banco “zf-order” e execute o script sql acima para criar e preencher as tabelas do banco. Após criar o banco edite o arquivo application.ini com as informações do banco de dados, caso tenha dúvida, visualize o artigo Entendendo modelos no zend framework.
Mapeando os relacionamentos
Agora que conheçemos os tipos de relacionamentos, tipos de mapeamentos e o banco de dados que iremos trabalhar, vamos mapear os relacionamentos das tabelas nos modelos, para isso crie os arquivos das abas abaixo na pasta “application/models”.
No modelo User mapeamos os modelos Product e Order como dependentes, já que o usuário cadastra produto e faz pedido, logo usuário é referênciado pelos modelos Product e Order que são dependentes do modelo User.
No modelo Product além de mapear o modelo OrderItem(que representa a tabela de junção do relacionamento N para N), como dependente, informamos que o modelo Product faz referência ao modelo User, perceba que nesse tipo de mapeamento precisamos informar o nome do modelo(refTableClass), coluna de referência(refColumns) e a coluna do modelo produto que corresponde a coluna de referência(columns).
No modelo Order é feito um mapeamento semelhante ao do produto, informando que o modelo OrderItem é dependente e o modelo User é referênciado para saber quem realizou o pedido.
Para finalizar no modelo OrderItem, mapeamos a referência aos modelos Order e Produto, que são os dois modelos que fazem o relacionamento N para N.
Trabalhando com os relacionamentos
Com os nossos modelos criados e devidamente mapeados, vamos explorar alguns métodos que utilizam os relacionamentos e facilita o resgate dos registros, para isso vamos utilizar o IndexController.php e sua view, index.phtml.
IndexController.php
index.phtml
Estrutura final do nosso projeto:
Resultado
Ao executar nossa aplicação iremos obter o seguinte resultado:
Confira o código-fonte do exemplo no GitHub.
E a quantidade de cada item do pedido? isso veremos em outro artigo, já que o método findManyToManyRowset() parou de retornar as colunas da tabela de junção, iremos estudar outras maneiras de realizar essa tarefa.