Doctrine 2 – Trabalhando com entidades mapeadas

 

Olá de novo! Na parte 1 do post – Doctrine 2 – Mapeando seu banco de dados – , vimos como mapear seu banco de dados (Não diga! Hehehe), e agora vamos ver como trabalhar com estas entidades.

Comecemos então por um exemplo bem fácil. Preciso criar uma categoria no banco de dados. O nosso banco de teste já possui algumas categorias cadastradas, mas ignore-as e vamos criar uma nova.

 

Lá no primeiro post, criamos o arquivo “bootstrap.php” certo? Lá definimos uma porção de coisas, e definimos inclusive uma variável chamada $entityManager. O EntityManager é o componente mais importante do Doctrine. Ele é o responsável, como o próprio nome diz, por administrar suas entidades. Com ele, e somente através dele, você conseguirá executar qualquer operação no banco de dados. Vamos trabalhar com ele e aos poucos vou explicando como ele funciona.

Obs.: Não estamos levando em consideração nenhuma estrutura ou padrões de desenvolvimento. Todos os exemplos são didáticos e é claro que quando você for implementar o que está vendo neste tutorial, deve pensar em uma melhor estrutura do que jogar os arquivos na raiz do diretório como estou fazendo aqui.

 

Criemos então, na raiz de nosso projeto, o arquivo “adicionaCategoria.php”. Ele deve ter o seguinte código:


 

// adicionaCategoria.php

/*
 * Fazendo o require do arquivo Bootstrap.php, podemos utilizar tudo que lá foi definido.
 * Estou falando principalmente do EntityManager, criado sobre a variável $entityManager
 */
require_once 'bootstrap.php';

/**
 * 
 *  instanciando a entidade Categoria
 */
$categoria = new Categoria;

/**
 * 
 * utilizando a função setNome 
 * Defino o nome da categoria a ser criada no banco de dados
 */
$categoria->setNome('Nova Categoria');

/**
 * 
 * Aqui o EM entra em ação. 
 * A função persist aguarda por um objeto  para colocá-lo na fila
 * de instruções a ser executada sobre o banco de dados
 */
$entityManager->persist($c);

/**
 * 
 * Novamente o EM age e invoca a função flush.
 * Esta é a responsável por pegar todas as intruções previamente preparadas
 * pelo persist e executá-las no banco de dados. 
 * Só a apartir daqui o banco é alterado de alguma forma.
 */
$entityManager->flush();

 

Fácil de entender, né? Se removermos os comentários, sobram 4 linhas de instrução para se gravar um novo registro no banco de dados. Agora rode o código e verifique em seu banco de dados a nova categoria adicionada. Você pode tratar o arquivo e adicionar uma mensagem positiva ou negativa caso a operação seja executada com sucesso ou não. Neste momento, não irá aparecer nada além de uma tela branca, pois não colocamos nenhuma mensagem.

Vamos recuperar um registro agora? Primeiro pelo ID. Crie o arquivo “buscaCategoriaByID.php” e adicione o código abaixo:

 

// buscaCategoriaByID.php

// você já sabe o motivo deste require
require_once 'bootstrap.php';

/**
 * 
 * Aqui não há a necessidade de instanciar a Entidade Categoria diretamente.
 * No método find, disposto pelo Entity Manager, passamos dois parâmetros:
 * O primeiro é o nome da Entidade, o segundo é o ID que buscamos.
 */
$categoria = $entityManager->find('Categoria', 2);
 
/**
 * 
 * Neste momento, já temos dentro da variável $categoria
 * toda a linha referente ao ID = 2 da tabela Categoria.
 * Utilizamos agora os gets para obter cada coluna em específico.
 * 
 * A instrução abaixo vai nos imprimir o nome da Categoria em questão.
 */
echo $categoria->getNome();

E que tal agora buscar uma categoria pelo seu nome?

// buscaCategoriaByNome.php

// você já sabe o motivo deste require
require_once 'bootstrap.php';

 /**
  * 
  * Agora vamos buscar uma categoria por nome, mas de um jeito um pouco diferente
  * Pegamos toda a Entidade Categoria e após isso buscamos apenas UM registro.
  * Para retornar todos os registros encontrados com os parâmetros passados,
  * altere a função findOneBy por findBy (esta última retorna um Array de Objetos)
  * 
  * Dentro do array, você pode passar quantos parâmetros for necessário para sua pesquisa.
  */
$categoria = $entityManager->getRepository('Categoria')->findOneBy(array('nome' => 'Hardware'));
 
 /**
  * 
  * Aqui vamos simplesmente imprimir na tela o ID da categoria encontrada.
  */
 echo $categoria->getId();

Prontinho… Vamos agora editar uma categoria. Analise o código abaixo:

// editarCategoria.php

// você já sabe o motivo deste require
require_once 'bootstrap.php';

/**
 * 
 * Começamos buscando em nosso banco de dados o registro que queremos alterar
 */
$update = $entityManager->find('Categoria', 3);

/**
 * 
 * Após isto, definimos os novos valores para as colunas. Neste caso, apenas o nome.
 */
$update->setNome('Categoria Alterada');

/**
 * 
 * O processo abaixo já é conhecido por você.
 * Não se lembra? Veja o arquivo adicionaCategoria.php
 */
$entityManager->persist($update);
$entityManager->flush();

 

Obviamente o Doctrine facilita algumas coisas. Você tem a opção de criar um método que verifica se o registro já existe no banco de dados. O método tem dois comportamentos: No primeiro, caso o registro não exista, o Doctrine cria-o no banco. O segundo, caso ele exista, o Doctrine apenas o altera. Isso faz com que você não se preocupe com INSERT ou UPDATE. Tudo que precisa é dar um “SAVE”. Em algum outro tutorial eu prometo abordar essa facilidade para vocês!

Agora, para fechar, vamos excluir uma categoria. No exemplo, estou excluindo a categoria de ID 4, se você não adicionou uma categoria conforme mostrado anteriormente, vai se deparar com um erro.

 

// removerCategoria.php

// você já sabe o motivo deste require
require_once 'bootstrap.php';

/**
 * 
 * A essa altura você já sabe o que essa linha faz
 */
$excluir = $entityManager->find('Categoria', 4);

/**
 * 
 * Função nova. ao invés de persist, agora utilizamos o remove,
 * passando nela o objeto à ser excluido.
 * 
 * Abaixo, o flush para concretizar a operação
 */
$entityManager->remove($excluir);
$entityManager->flush();

 

Tudo bem até agora? Espero que sim. Vamos rapidamente então mostrar o funcionamento da entidade Produto. O legal agora é que temos um relacionamento para tratar. Você já trabalhou com JOINS em suas querys? Se não, não tem problema. Esqueça tudo isso por quê o Doctrine faz a mágica por nós.

A partir de alguns produtos já cadastrados previamente no banco, vamos pegar e apresentar seus nomes, e além disso, tendo apenas o ID de sua categoria, vamos apresentar o nome dela também.

Analise o código abaixo.

 

// apresentaProduto.php

// você já sabe o motivo deste require
require_once 'bootstrap.php';

/**
 * 
 * Função igual à vista anteriormente, só mudamos o nome da Entidade
 */
$produto = $entityManager->find('Produto', 3);

// Ok, você já sabe o que isto faz
$nome = $produto->getNome();

/**
 * 
 * Isto é novo! Acessando a função getCategoria() dentro da entidade Produto
 * uma vez que esta faz referência à entidade Categoria, posso então acessar
 * TODO E QUALQUER método da entidade Categoria. 
 * 
 * Lembre-se. O getNome da linha 14 faz referência à entidade Produto,
 * já o getNome da linha abaixo faz referência à classe Categoria
 */
$categoria = $produto->getCategoria()->getNome();

//para encerrar, apresento os dois dados capturados.

echo $nome . "<br />";
echo $categoria;

 

Viu como é fácil fazer querys que antes precisavam de Joins? O Doctrine facilita bastante o desenvolvimento de aplicações cujo banco seja complexo ou cheio de relacionamentos.

Como o Doctrine trabalha inteiramente com objetos, se formos adicionar um produto agora à nossa lista, temos que tomar cuidado ao indicar a categoria. Não podemos simplesmente pegar o ID da categoria e inserir no campo. Temos que tratá-la também como um objeto, ou seja, estamos adicionando um OBJETO no campo com relacionamento, e não mais apenas um número inteiro. Veja o código abaixo que isto ficará mais claro:

 

// adicionaProduto.php

// você já sabe o motivo deste require
require_once 'bootstrap.php';

/**
 * 
 * No primeiro momento, antes de adicionar o produto, devemos recuperar 
 * a categoria à qual este produto pertence
 */
$categoria = $entityManager->find('Categoria', 1);

// instanciamos um novo produto (mais uma vez, obrigado autoload!)
$produto = new Produto;

//setamos o nome deste produto
$produto->setNome('Placa de Som');

/**
 * 
 * Aqui acontece uma mágica. Já recuperamos o objeto da categoria que desejamos,
 * basta adicioná-lo agora ao produto, através do método setCategoria
 */
$produto->setCategoria($categoria);

// aqui já está dominado, certo?
$entityManager->persist($produto);
$entityManager->flush();

 

Pronto, rápido e fácil. O mesmo processo se dá quando há a necessidade de alteração. É preciso buscar a categoria em questão e utilizar o método setCategoria() para fixá-la ao produto.

Chega então ao fim o nosso tutorial básico de introdução ao Doctrine 2. Agora você já tem uma ideia de como ele funciona e como integrar ao seu projeto (se você estiver usando algum framework, o processo de integração varia bastante). Cabe à você agora correr atrás da documentação do projeto Doctrine e ver tudo que se pode fazer utilizando-o. Há exemplo de todos os tipos de relação lá, tanto uni como bilateral. Você também irá descobrir que em caso de ligações muitos-para-muitos bilateral, onde normalmente haveria a necessidade de uma terceira tabela para unir os dados relacionados, com o uso do Doctrine esta tabela é desnecessária. Como? Mágica, hehehehe

 

Para baixar todo o código criado nas duas partes do tutorial, clone o repositório no github com o comando

git clone https://github.com/ricardobrusch/tutorialDoctrine.git

Ou acesse o link para baixar como ZIP (Tutorial Doctrine 2 no GitHub)

Espero que tenham gostado e se ficarem com dúvidas ou tiverem sugestões, opiniões ou seja o que for , utilizem os comentários abaixo e vamos compartilhar nosso conhecimento!

 


Publicado em Banco de Dados, Desenvolvimento, Tecnologia
  • Cléber Alves

    Que belo artigo. Bem objetivo, didático e organizado. Trabalho com PHP a quase 4 anos, porem sempre achei bacana a experiencia que o Hibernate dava no Java e no AspNet. Assim que der, irei fazer testes com o Doctrine e postarei aqui minhas experiencias com o mesmo. Parabéns pelo artigo, e o agradeço a citação! Abraço.

  • http://www.ricardobrusch.com.br Ricardo Brusch

    Eu que agradeço pela dica de post, Cléber! Espero que tenha sucesso em seus testes, e que o Doctrine possa te proporcionar os melhoramentos que almeja para teus projetos. Um forte abraço!

  • http://edinaldofox.com.br Jose Edinaldo

    Muito bom, bem pratico, e facil de entender, ja aprend 50%, usushushs vlw!

    • Ricardo Brusch

      Agradeço o comentário, Jose, e fico feliz que tenha sido útil à você! Tentei explicar da maneira mais prática possível para ficar fácil de ser assimilado e absorvido, com o mínimo de termos técnicos nos comentários. Abraço!

  • Manoel

    Ricardo. Parabéns. Já vi de tudo aqui na internet pra entender alguns detalhes do doctrine e resolvi aqui.

    • Manoel

      Manda bem demais, cara! =D

    • Ricardo Brusch

      Bah tchê, fico feliz em poder ter te ajudado. Perdão pela demora em responder, tô numa correria ultimamente… Espero poder retomar esse série de posts, e adicionar mais coisa sobre o Doctrine 2, já que temos pouco conteúdo disponível em português (pelo menos gratuito na net)

      Abração e sucesso!

  • Larissa Masson

    Parabéns pelo artigo. Só tenho uma dúvida, o find retorna apenas um registro, como faria para retornar todos os registros com tal campo = a “F’ po r exemplo?

    • Ricardo Brusch

      Oi Larissa, obrigado pelo comentário! Assim como o método find() retorna apenas um registro, temos o findAll() que retorna uma listagem completa e, se aplicando o caso da tua dúvida, podemos usar o findBy(), onde se passa um array com os parâmetros desejados.

      Experimente algo tipo $entity->findBy(array(‘campo’ => ‘F’));

      Ele pode ser incrementado com mais parâmetros, para personalizar bem a tua query e retornar exatamente o que tu precisa.

      Aqui tem mais sobre o método -> http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-objects.html#by-simple-conditions

      Sucesso nos teus projetos! Abração!

      • Larissa Masson

        Eu não sabia que existiam esses métodos.. mas descobri que o find na verdade retorna todos, porém como estava testando com var_dump ele apresentava apenas um. Com um foreach consegui ter acesso a tudo. Mas vou dar uma olha nestes outros métodos, obrigada ^^.

  • Márcio Carvalho

    To tentando fazer um sistema usando doctrine e da um erro quando vou adicionar um registro em uma tabela que tem relacionamento, aparece que tenho que acrescentar cascade=persist nas anotações

  • barratec sistemas

    Muito Bom ! Parabéns pela iniciativa… Continue por favor .. Abs !

    • Ricardo Brusch

      Valeeeu!! Estou tentando me organizar para voltar a escrever alguns tutoriais para o blog, obrigado pelo comentário e pelo incentivo! Abração!

  • Deison Ribeiro

    Oi, Ricardo, tudo legal?

    Encontrei um erro enquanto testava os arquivos.

    Linha 28 “$entityManager->persist($c);” do arquivo “adicionaCategoria.php”

    A variável não é $c, é $categoria.
    😀

    Espero ter ajudado.

    E obrigado por contribui com esse conteúdo, está sendo bastante útil para o meu aprendizado.

    Forte abraço,
    Deison.

    • Ricardo Brusch

      Cara, obrigado pelo comentário e pelo alerta! Já corrigi no Github (com os devidos créditos! =D ), e assim que possível atualizo aqui no blog tbm =D

      Fico feliz que o conteúdo está sendo útil! Forte abraço e bons estudos!!

  • Schmidt

    Boa tarde. Primeiramente parabéns pelo tutorial, me ajudou bastante aqui.
    Tenho uma duvida exemplo que tenho a tabela produto {id, nome, valor} e a tabela img { id, descricao, id_produto} teria como ao puxar o produto já puxar a lista de img que seja correspondente a cada produto???
    Desde já agradeço sua colaboração.

Volte Sempre!
Meus artigos te ajudaram de alguma forma e você não sabe como me agradecer? Que tal me pagar uma Coca-Cola bem gelada?

Sobre o autor

Me chamo Ricardo Brusch, sou programador e desenvolvedor de sistemas para internet. Também sou aspirante a escritor, e você pode ler alguns de meus contos malucos em contos.ricardobrusch.com.br.
Parceiros





Publicidade