RAD com Doctrine ORM Guilherme Blanco
PHP Developers!
Quem é você? Peão de fazenda por 6 anos Desenvolvedor Web desde 1998, PHP desde 2001 Responsável pelo site  http://windows.php.net Membro do grupo ProPHP Desenvolvedor do core do Doctrine Commiter da framework PHP Symfony, Zend Framework, PHP-Doc, PHP-Wiki, PHP-Windows e PHP-Web, ... Apaixonado por jogos da série Age of Empires
O que é ORM? Da Wikipedia: “ Mapeamento objeto-relacional  (ou  ORM ) é uma técnica de desenvolvimento utilizada para reduzir a  impedância  da  programação orientada aos objetos  utilizando  bancos de dados relacionais . As  tabelas  do  banco de dados  são representadas através de  classes  e os registros de cada tabela são representados como instâncias das classes correspondentes.”
Malditos Objetos! Aplicações PHP dependem mais de código OO Mas... Como recupero objetos do meu Banco? OO não mapeia naturalmente para SGBD Relacional: identificador, estado, comportamento, encapsulação, relacionamentos, atributos, etc Todo este sofrimento se resume à estas palavras simples em Inglês: “ impedance mismatch ”
It’s RAD baby! Do dicionário: “ Slang and/or abbreviation for the word ‘radical’.” “ Calão e/ou abreviatura da palavra ‘radical’.” Da Wikipedia: “ Rapid application development (RAD) , é um modelo de processo de desenvolvimento de software iterativo e incremental que enfatiza um ciclo de desenvolvimento extremamente curto (entre 60 e 90 dias).”
O que é Doctrine? Doctrine é uma ferramenta de ORM construída para trabalhar com PHP 5.2.3+ Baseada primariamente em Java Hibernate Influenciada por ActiveRecord do Ruby on Rails Projeto iniciado oficialmente em 2006 Versão 1.0 lançada em Setembro 2008
As camadas envolvidas
Fatos da vida... Por que eu deveria utilizar? Torna problemas difíceis muito mais fáceis Reduz tempo de desenvolvimento Reduz custo... E eu gosto de $$$! =) Resolvemos o problema da fome no mundo? Não, e também não resolve  todos  os seus problemas! Ajuda mais do que atrapalha Por que eu falei, p****!
Recursos São tantos… Abstração da Base de Dados Tarefas (Tasks) via CLI Arquivos de Schema Data fixtures Caching DQL Listeners (Query, Record, Connection, …) Behaviors …
Abstração da Base de Dados Doctrine depende de PDO e suporta qualquer driver que ela possui: Mysql Sqlite Pgsql Oracle Mssql Firebird Informix Implementando Connection e DataDict, você pode suportar outros drivers também
1, 2, 3... VAMOS LÁ!
Tarefas via CLI <?php define('DSN', 'mysql://user:password@localhost:3306/dbname'); require_once 'path/to/Doctrine.php'; spl_autoload_register(array('Doctrine', 'autoload')); Doctrine_Manager::connection(DSN, 'sandbox'); Doctrine_Manager::getInstance()->setAttribute('model_loading', 'conservative'); $cli = new Doctrine_Cli(array( 'data_fixtures_path'  =>  'path/to/data_fixtures', 'models_path'  =>  'path/to/models', 'migrations_path'  =>  'path/to/migrations', 'sql_path'  =>  'path/to/sql', 'yaml_schema_path'  =>  'path/to/yaml_schema' )); $cli->run($_SERVER['argv']);
Tarefas via CLI Tarefas básicas de CLI Do Schema YAML para Modelos PHP php ./doctrine.php generate-models-yaml Gerando SQL a partir dos Modelos php ./doctrine.php generate-sql Gerando Tabelas no BD a partir dos Modelos php ./doctrine.php create-tables Carregando Data Fixture nas tabelas do BD php ./doctrine.php load-data Quer algo mais? Lista todas as tarefas e ajuda... php ./doctrine.php help
Nosso problema: Blog
A ARTE DE SER VAGABUNDO...
 
 
 
 
 
Data Fixtures Fácil especificar entradas m2m Nós fizemos primeiro, não Rails! =P
Caching Drivers suportados:  APC Array Db Memcache Xcache Mecanismos de Caching: Query Cache Result Cache
Caching $cacheDriver = new Doctrine_Cache_Memcache(array( 'servers' => array( array( 'host' => 'localhost', 'port' => 11211, 'persistent' => true, ), ), 'compression' => false )); Manager level: $manager->setAttribute(Doctrine::ATTR_QUERY_CACHE, $cacheDriver); Connection level: $conn->setAttribute(Doctrine::ATTR_QUERY_CACHE, $cacheDriver); Query level: $query->useQueryCache($cacheDriver);
Doctrine Query Language Dialeto SQL Orientado a Objeto usado para recuperar dados
DQL DQL torna difíceis consultas SQL simples Traz POO para suas consultas à base de dados Processada e convertida para seu SGBD específico Processamento da DQL é cacheado Funções de DB específicas também são suportadas. Expressões podem ser convertidas também
Quero ver exemplo! FROM BlogPost p INNER JOIN p.Author a LEFT JOIN p.Tags t SELECT b.id AS b__id, b.title AS b__title, b.body AS b__body, b.author_id AS b__author_id, b.slug AS b__slug, b.created_at AS b__created_at, b.updated_at AS b__updated_at, a.id AS a__id, a.name AS a__name, t.id AS t__id, t.name AS t__name  FROM blog_post b INNER JOIN author a ON b.author_id = a.id  LEFT JOIN blog_post_tag b2 ON b.id = b2.blog_post_id  LEFT JOIN tag t ON t.id = b2.tag_id
Run Forest, run! php ./doctrine.php dql “FROM BlogPost b INNER JOIN b.Author a LEFT JOIN b.Tags t WHERE a.name = ?” “Guilherme Blanco”
DQL php ./doctrine.php dql “ SELECT bp.*, COUNT(t.id) AS num_tags FROM BlogPost bp LEFT JOIN bp.Tags t GROUP BY bp.id”
Named Query Criar Obter Executar
Eu amo a vagabundagem...
TRABALHANDO COM OBJETOS
Accessor/Mutator 3 tipos possíveis, basta escolher! Fáceis de usar...
Sobrescrevendo Sobrescrever accessors e mutators facilmente Funções reconhecidas e invocadas como accessors normais Utilize _get/_set para evitar loop infinito
Sobrescrevendo
Que hidratante vocês usam? Doctrine te provê : Objetos Arrays Sem hidratação Escalar Escalar simples
Que hidratante vocês usam?
Relacionamentos simples Relacionamentos são como deveriam ser! ;) Diferentes tipos de relacionamento suportados: one2one one2many many2one many2many s elf Especifique relacionamentos de forma linear
Relacionamentos tipo orgia! m2m Objeto de referência é usado de forma transparente Não é necessário referenciar o objeto manualmente Fácil de armazenar dados extras com tabelas de apoio
Relacionamentos tipo orgia! m2m Fácil de se: relacionar (link) largar (unlink) Especifica novos objetos de forma linear Anexar objetos existentes
Atualizando dados Recuperar a atualizar Atualizar com uma consulta DQL Atualizações através de DQL não lançam eventos
Removendo dados Recuperar e remover Remover sem recuperar DQL delete dispara consultas individuais
Listeners & Hooks Transaction Listeners: (pre|post)Transaction(Begin|Rollback|Commit)  (pre|post)(Create|Rollback|Release)Savepoint Connection Listeners: (pre|post)(Prepare|Exec|(Stmt)?Execute|Fetch(All)?) Query Listeners: (pre|post)Hydrate preDql(Select|Update|Delete) Record Listeners & Hooks: (pre|post)(Save|Insert|Update|Delete|Validate|Serialize)
Behaviors Adicionam funcionalidade extra Reusabilidade de código Manutenção Poupa tempo e $$$ Possibilidade de criar seu próprio comportamento
Behaviors Timestampable Sluggable Versionable I18N SoftDelete NestedSet Geographical Blameable (1.2) Sortable (1.2)
QUERO VER EXEMPLO!!!!
O que aconteceu? Colunas automaticamente criadas Timestampable - Automaticamente define created_at e updated_at ao salvar Sluggable - Automaticamente cria um único e legível nome de identificação do objeto (slug)
Futuro – Doctrine 2.0 Praticamente reescrita total do código. PHP 5.3+ PHPUnit como Unit Test Suite Desacoplamento dos componentes Behaviors, Validators, YAML Schema, Data Fixtures, etc Separação total entre DBAL – ORM  DQL Compiler Maior concentração em funcionalidades específicas de ORM
Doctrine 2.0 Code coverage bate 69%, com 262 unit tests Performance:
Doctrine 2.0
Doctrine ORM for PHP
E aí, crianças… ALGUMA PERGUNTA?!
Doctrine Project Obrigado pela paciência! http://www.doctrine-project.org [email_address] @guilhermeblanco #twitter Follow the Doctrine…

Desenvolvimento Agil Com Doctrine Orm

  • 1.
    RAD com DoctrineORM Guilherme Blanco
  • 2.
  • 3.
    Quem é você?Peão de fazenda por 6 anos Desenvolvedor Web desde 1998, PHP desde 2001 Responsável pelo site http://windows.php.net Membro do grupo ProPHP Desenvolvedor do core do Doctrine Commiter da framework PHP Symfony, Zend Framework, PHP-Doc, PHP-Wiki, PHP-Windows e PHP-Web, ... Apaixonado por jogos da série Age of Empires
  • 4.
    O que éORM? Da Wikipedia: “ Mapeamento objeto-relacional (ou ORM ) é uma técnica de desenvolvimento utilizada para reduzir a impedância da programação orientada aos objetos utilizando bancos de dados relacionais . As tabelas do banco de dados são representadas através de classes e os registros de cada tabela são representados como instâncias das classes correspondentes.”
  • 5.
    Malditos Objetos! AplicaçõesPHP dependem mais de código OO Mas... Como recupero objetos do meu Banco? OO não mapeia naturalmente para SGBD Relacional: identificador, estado, comportamento, encapsulação, relacionamentos, atributos, etc Todo este sofrimento se resume à estas palavras simples em Inglês: “ impedance mismatch ”
  • 6.
    It’s RAD baby!Do dicionário: “ Slang and/or abbreviation for the word ‘radical’.” “ Calão e/ou abreviatura da palavra ‘radical’.” Da Wikipedia: “ Rapid application development (RAD) , é um modelo de processo de desenvolvimento de software iterativo e incremental que enfatiza um ciclo de desenvolvimento extremamente curto (entre 60 e 90 dias).”
  • 7.
    O que éDoctrine? Doctrine é uma ferramenta de ORM construída para trabalhar com PHP 5.2.3+ Baseada primariamente em Java Hibernate Influenciada por ActiveRecord do Ruby on Rails Projeto iniciado oficialmente em 2006 Versão 1.0 lançada em Setembro 2008
  • 8.
  • 9.
    Fatos da vida...Por que eu deveria utilizar? Torna problemas difíceis muito mais fáceis Reduz tempo de desenvolvimento Reduz custo... E eu gosto de $$$! =) Resolvemos o problema da fome no mundo? Não, e também não resolve todos os seus problemas! Ajuda mais do que atrapalha Por que eu falei, p****!
  • 10.
    Recursos São tantos…Abstração da Base de Dados Tarefas (Tasks) via CLI Arquivos de Schema Data fixtures Caching DQL Listeners (Query, Record, Connection, …) Behaviors …
  • 11.
    Abstração da Basede Dados Doctrine depende de PDO e suporta qualquer driver que ela possui: Mysql Sqlite Pgsql Oracle Mssql Firebird Informix Implementando Connection e DataDict, você pode suportar outros drivers também
  • 12.
    1, 2, 3...VAMOS LÁ!
  • 13.
    Tarefas via CLI<?php define('DSN', 'mysql://user:password@localhost:3306/dbname'); require_once 'path/to/Doctrine.php'; spl_autoload_register(array('Doctrine', 'autoload')); Doctrine_Manager::connection(DSN, 'sandbox'); Doctrine_Manager::getInstance()->setAttribute('model_loading', 'conservative'); $cli = new Doctrine_Cli(array( 'data_fixtures_path' => 'path/to/data_fixtures', 'models_path' => 'path/to/models', 'migrations_path' => 'path/to/migrations', 'sql_path' => 'path/to/sql', 'yaml_schema_path' => 'path/to/yaml_schema' )); $cli->run($_SERVER['argv']);
  • 14.
    Tarefas via CLITarefas básicas de CLI Do Schema YAML para Modelos PHP php ./doctrine.php generate-models-yaml Gerando SQL a partir dos Modelos php ./doctrine.php generate-sql Gerando Tabelas no BD a partir dos Modelos php ./doctrine.php create-tables Carregando Data Fixture nas tabelas do BD php ./doctrine.php load-data Quer algo mais? Lista todas as tarefas e ajuda... php ./doctrine.php help
  • 15.
  • 16.
    A ARTE DESER VAGABUNDO...
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
    Data Fixtures Fácilespecificar entradas m2m Nós fizemos primeiro, não Rails! =P
  • 23.
    Caching Drivers suportados: APC Array Db Memcache Xcache Mecanismos de Caching: Query Cache Result Cache
  • 24.
    Caching $cacheDriver =new Doctrine_Cache_Memcache(array( 'servers' => array( array( 'host' => 'localhost', 'port' => 11211, 'persistent' => true, ), ), 'compression' => false )); Manager level: $manager->setAttribute(Doctrine::ATTR_QUERY_CACHE, $cacheDriver); Connection level: $conn->setAttribute(Doctrine::ATTR_QUERY_CACHE, $cacheDriver); Query level: $query->useQueryCache($cacheDriver);
  • 25.
    Doctrine Query LanguageDialeto SQL Orientado a Objeto usado para recuperar dados
  • 26.
    DQL DQL tornadifíceis consultas SQL simples Traz POO para suas consultas à base de dados Processada e convertida para seu SGBD específico Processamento da DQL é cacheado Funções de DB específicas também são suportadas. Expressões podem ser convertidas também
  • 27.
    Quero ver exemplo!FROM BlogPost p INNER JOIN p.Author a LEFT JOIN p.Tags t SELECT b.id AS b__id, b.title AS b__title, b.body AS b__body, b.author_id AS b__author_id, b.slug AS b__slug, b.created_at AS b__created_at, b.updated_at AS b__updated_at, a.id AS a__id, a.name AS a__name, t.id AS t__id, t.name AS t__name FROM blog_post b INNER JOIN author a ON b.author_id = a.id LEFT JOIN blog_post_tag b2 ON b.id = b2.blog_post_id LEFT JOIN tag t ON t.id = b2.tag_id
  • 28.
    Run Forest, run!php ./doctrine.php dql “FROM BlogPost b INNER JOIN b.Author a LEFT JOIN b.Tags t WHERE a.name = ?” “Guilherme Blanco”
  • 29.
    DQL php ./doctrine.phpdql “ SELECT bp.*, COUNT(t.id) AS num_tags FROM BlogPost bp LEFT JOIN bp.Tags t GROUP BY bp.id”
  • 30.
    Named Query CriarObter Executar
  • 31.
    Eu amo avagabundagem...
  • 32.
  • 33.
    Accessor/Mutator 3 tipospossíveis, basta escolher! Fáceis de usar...
  • 34.
    Sobrescrevendo Sobrescrever accessorse mutators facilmente Funções reconhecidas e invocadas como accessors normais Utilize _get/_set para evitar loop infinito
  • 35.
  • 36.
    Que hidratante vocêsusam? Doctrine te provê : Objetos Arrays Sem hidratação Escalar Escalar simples
  • 37.
  • 38.
    Relacionamentos simples Relacionamentossão como deveriam ser! ;) Diferentes tipos de relacionamento suportados: one2one one2many many2one many2many s elf Especifique relacionamentos de forma linear
  • 39.
    Relacionamentos tipo orgia!m2m Objeto de referência é usado de forma transparente Não é necessário referenciar o objeto manualmente Fácil de armazenar dados extras com tabelas de apoio
  • 40.
    Relacionamentos tipo orgia!m2m Fácil de se: relacionar (link) largar (unlink) Especifica novos objetos de forma linear Anexar objetos existentes
  • 41.
    Atualizando dados Recuperara atualizar Atualizar com uma consulta DQL Atualizações através de DQL não lançam eventos
  • 42.
    Removendo dados Recuperare remover Remover sem recuperar DQL delete dispara consultas individuais
  • 43.
    Listeners & HooksTransaction Listeners: (pre|post)Transaction(Begin|Rollback|Commit) (pre|post)(Create|Rollback|Release)Savepoint Connection Listeners: (pre|post)(Prepare|Exec|(Stmt)?Execute|Fetch(All)?) Query Listeners: (pre|post)Hydrate preDql(Select|Update|Delete) Record Listeners & Hooks: (pre|post)(Save|Insert|Update|Delete|Validate|Serialize)
  • 44.
    Behaviors Adicionam funcionalidadeextra Reusabilidade de código Manutenção Poupa tempo e $$$ Possibilidade de criar seu próprio comportamento
  • 45.
    Behaviors Timestampable SluggableVersionable I18N SoftDelete NestedSet Geographical Blameable (1.2) Sortable (1.2)
  • 46.
  • 47.
    O que aconteceu?Colunas automaticamente criadas Timestampable - Automaticamente define created_at e updated_at ao salvar Sluggable - Automaticamente cria um único e legível nome de identificação do objeto (slug)
  • 48.
    Futuro – Doctrine2.0 Praticamente reescrita total do código. PHP 5.3+ PHPUnit como Unit Test Suite Desacoplamento dos componentes Behaviors, Validators, YAML Schema, Data Fixtures, etc Separação total entre DBAL – ORM DQL Compiler Maior concentração em funcionalidades específicas de ORM
  • 49.
    Doctrine 2.0 Codecoverage bate 69%, com 262 unit tests Performance:
  • 50.
  • 51.
  • 52.
    E aí, crianças…ALGUMA PERGUNTA?!
  • 53.
    Doctrine Project Obrigadopela paciência! http://www.doctrine-project.org [email_address] @guilhermeblanco #twitter Follow the Doctrine…