Doctrine 2
Camada de Persistência para PHP 5.3+
Guilherme Blanco, Yahoo!
sábado, 26 de junho de 2010
Quem sou eu?
Web developer a mais de 10 anos
Evangelista Open Source
Trabalha para Yahoo!
Contribui para... ...Doctrine ...Zend Framework ...Symfony ...PHP etc
Gosta de cantar e pescar no tempo livre! =)
sábado, 26 de junho de 2010
Quem sou eu?
http://www.twitter.com/guilhermeblanco
http://www.facebook.com/guilhermeblanco
sábado, 26 de junho de 2010
Doctrine 2
sábado, 26 de junho de 2010
Doctrine 2
PHP 5.3+
100% do código reescrito
Código totalmente em namespaces
sábado, 26 de junho de 2010
Doctrine 2
Ferramentas usadas: phpUnit Unit test Phing Pacotes e distribuição Symfony Components
YAMLConsole
Sismo Continuous Integration GIT Controle de versão do código JIRA Gerenciamento de bugs Trac Timeline, código fonte & visualizar alterações
sábado, 26 de junho de 2010
Doctrine 2
Três principais pacotes: Common
DBAL
ORM
sábado, 26 de junho de 2010
Doctrine\Common\Cache
Drivers Suportados: APCCache
$cacheDriver = new \Doctrine\Common\Cache\ApcCache();
MemcacheCache$memcache = new \Memcache();$memcache->addServer('memcache_host', 11211);
$cacheDriver = new \Doctrine\Common\Cache\MemcacheCache();$cacheDriver->setMemcache($memcache);
XcacheCache$cacheDriver = new \Doctrine\Common\Cache\XcacheCache();
sábado, 26 de junho de 2010
Doctrine\Common\Cache
Cache Drivers Interface:
interface \Doctrine\Common\Cache\Cache {function setNamespace($namespace);function getIds();
function fetch($id);
function contains($id);
function save($id, $data, $lifeTime = 0);
function delete($id);function deleteAll();
function deleteByRegex($regex);function deleteByPrefix($prefix);function deleteBySuffix($suffix);
}
sábado, 26 de junho de 2010
Doctrine\Common
[email protected]:doctrine/common.git
Cache Drivers
Class Loader
sábado, 26 de junho de 2010
Doctrine\Common\ClassLoader
Implements PSR #0 PSR = PHP Standards Recommendation
Interoperabilidade Técnica entre bibliotecas Symfony, Zend Framework, Doctrine, Agavi, PEAR2/Pyrus,
Lithium, Flow3, Solar, etc
Possível merge no core do PHP: SplClassLoader http://wiki.php.net/rfc/splclassloader
sábado, 26 de junho de 2010
Doctrine\Common\ClassLoader
Como usar:
require_once '/path/to/lib/Doctrine/Common/ClassLoader.php';
$doctrineClassLoader = new \Doctrine\Common\ClassLoader( 'Doctrine', '/path/to/lib/Doctrine');
$doctrineClassLoader->register();
sábado, 26 de junho de 2010
Doctrine\Common
[email protected]:doctrine/common.git
Cache Drivers
Class Loader
Collections
sábado, 26 de junho de 2010
Doctrine\Common\Collections
Solução inspirada na interface java.util.Collection
Array simples em PHP são difíceis de manipular
...mas implementações de array customizadas não são compatíveis com as funções de array_*
Uso intenso de Closures
Implementação SplArray do usuário Onde estão os desenvolvedores do PHP?
sábado, 26 de junho de 2010
Doctrine\Common
[email protected]:doctrine/common.git
Cache Drivers
Class Loader
Collections
Lexer
sábado, 26 de junho de 2010
Doctrine\Common
[email protected]:doctrine/common.git
Cache Drivers
Class Loader
Collections
Lexer
Annotations Parser
sábado, 26 de junho de 2010
Doctrine\Common\Annotations
Suporte à Annotations similar ao Java
Define informações de metadados em classes
Extremamente extensível e reutilizável
Supre uma funcionalidade inexistente no PHP Novamente, onde estão os desenvolvedores do PHP? RFC já escrito: http://wiki.php.net/rfc/annotations
sábado, 26 de junho de 2010
Doctrine\Common\AnnotationsAnnotations ::= Annotation {[ "*" ]* [Annotation]}*Annotation ::= "@" AnnotationName ["(" [Values] ")"]AnnotationName ::= QualifiedName | SimpleName | AliasedNameQualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleNameAliasedName ::= Alias ":" SimpleNameNameSpacePart ::= identifierSimpleName ::= identifierAlias ::= identifierValues ::= Array | Value {"," Value}*Value ::= PlainValue | FieldAssignmentPlainValue ::= integer | string | float | boolean | Array | AnnotationFieldAssignment ::= FieldName "=" PlainValueFieldName ::= identifierArray ::= "{" ArrayEntry {"," ArrayEntry}* "}"ArrayEntry ::= Value | KeyValuePairKeyValuePair ::= Key "=" PlainValueKey ::= string | integer
sábado, 26 de junho de 2010
Doctrine\Common\Annotations
Criando classes de Annotations:
final class \Doctrine\ORM\Mapping\Entity extends \Doctrine\Common\Annotations\Annotation { public $repositoryClass;}
Usando as Annotations:
namespace MyProject\Entity;
/** * @Entity(repositoryClass="Repository\UserRepository") */class User { // ... }
sábado, 26 de junho de 2010
Doctrine\Common\Annotations
Lendo Annotations:
$reader = new \Doctrine\Common\Annotations\AnnotationReader( new \Doctrine\Common\Cache\ArrayCache());$reader->setDefaultAnnotationNamespace( 'Doctrine\ORM\Mapping\\'); $class = new \ReflectionClass('MyProject\Entity\User');$classAnnotations = $reader->getClassAnnotations($class);
echo $classAnnotations['Doctrine\ORM\Mapping\Entity'] ->repositoryClass;
sábado, 26 de junho de 2010
Doctrine\Common\Annotationsinterface \Doctrine\Common\Annotations\AnnotationReader { function setDefaultAnnotationNamespace($defaultNamespace);
function setAnnotationNamespaceAlias($namespace, $alias);
function getClassAnnotations(\ReflectionClass $class);
function getClassAnnotation(\ReflectionClass $class, $annot);
function getPropertyAnnotations(\ReflectionProperty $property);
function getPropertyAnnotation( \ReflectionProperty $property, $annot );
function getMethodAnnotations(\ReflectionMethod $method);
function getMethodAnnotation(\ReflectionMethod $method, $annot);}
sábado, 26 de junho de 2010
Doctrine\DBAL
[email protected]:doctrine/dbal.git
DataBase Abstraction Layer construído sobre a PDO e drivers proprietários
Drivers suportados: DB2 Microsoft SQL Server (pdo_sqlsrv & sqlsrv) MySQL PostgreSQL Oracle SQLite
sábado, 26 de junho de 2010
Doctrine\DBAL
API para introspecção e gerenciamento de schemas de Bancos de Dados melhorado
Pode se tornar um padrão para DBAL em PHP 5.3 no futuro, tal como MDB2 para PEAR1
Inspirado em ezcDatabase, MDB2 e Zend_Db
Talvez podemos fazer acontecer para a PEAR2
sábado, 26 de junho de 2010
Doctrine\DBALinterface \Doctrine\DBAL\Connection { // API para manipulação de dados
/* Executa um SQL DELETE statement numa tabela. */ function delete($tableName, array $identifier);
/* Executa um SQL UPDATE statement numa tabela. */ function update($tableName, array $data, array $identifier);
/* Insere uma linha na tabela com os dados especificados. */ function insert($tableName, array $data);
/* Prepara um SQL statement. Retorna um DBAL\Statement */ function prepare($statement);
/* Aplica um SQL statement e retorna # linhas afetadas. */ function exec($statement);
// ...
sábado, 26 de junho de 2010
Doctrine\DBAL // API para Transação
/* Retorna o nível de profundidade da transação corrente. */ function getTransactionNestingLevel();
/* Executa uma função em uma transação. */ function transactional(\Closure $func);
/* Inicia uma transação suspendendo o modo auto-commit. */ function beginTransaction();
/* Aplica a transação corrente. */ function commit();
/* Cancela qualquer alteração na base da transação corrente. */ function rollback();
/* Checa se a transação corrente é marcada como somente rollback. */ function isRollbackOnly();
// ...
sábado, 26 de junho de 2010
Doctrine\DBAL // API para obtenção de dados
/* Executa consulta SQL e retorna a 1a. linha num array assoc. */ function fetchAssoc($statement, array $params = array());
/* Executa consulta SQL e retorna a 1a. linha num array numérico. */ function fetchArray($statement, array $params = array());
/* Executa consulta SQL e retorna o valor da 1a. coluna. */ function fetchColumn( $statement, array $params = array(), $colnum = 0 );
/* Executa consulta SQL e retorna todo resultado num array assoc. */ function fetchAll($sql, array $params = array());}
sábado, 26 de junho de 2010
Doctrine\DBAL\Types
Ponto centralizado para conversão de tipos Do Banco de Dados para PHP Do PHP para o Banco de Dados
Independente do Banco de Dados
Acesso ao dialeto específico da Base via Platforma
Extensível
sábado, 26 de junho de 2010
Doctrine\DBAL\Types
Novo tipo é só implementar uma classe abstrata:interface \Doctrine\DBAL\Types\Type { function convertToDatabaseValue( $value, AbstractPlatform $platform );
function convertToPHPValue( $value, AbstractPlatform $platform );
function getSqlDeclaration( array $fieldDeclaration, AbstractPlatform $platform ); function getName();
function getBindingType();}
sábado, 26 de junho de 2010
Doctrine\DBALclass \MyProject\DataTypes\MyObjectType extends \Doctrine\DBAL\Types\Type{ public function getSqlDeclaration( array $fieldDeclaration, AbstractPlatform $platform ) { return $platform->getClobTypeDeclarationSQL($fieldDeclaration); }
public function convertToDatabaseValue( $value, AbstractPlatform $platform ) { return serialize($value); }
public function convertToPHPValue($value, AbstractPlatform $platform) { $value = (is_resource($value)) ? stream_get_contents($value) : $value; return unserialize($value); }
public function getName() { return "my-object"; }}
sábado, 26 de junho de 2010
Doctrine\DBAL\Types
Finalmente, faça o Doctrine saber sobre seu tipo:\Doctrine\DBAL\Types\Type::addType( "my-object", "\MyProject\DataTypes\MyObjectType");
Então você pode usar nas suas Entidades!/** * @Entity * @Table(name="files") */class File { // ...
/** * @Column(type="my-object") */ protected $content;}
sábado, 26 de junho de 2010
Doctrine\DBAL
Criando um schema:$platform = $em->getConnection()->getDatabasePlatform();
$schema = new \Doctrine\DBAL\Schema\Schema(); $table = $schema->createTable("users"); $table->addColumn("id", "integer", array("unsigned" => true));$table->addColumn("name", "string", array("length" => 32));$table->setPrimaryKey(array("id"));
// obtenha as consultas para criar este schema.$queries = $schema->toSql($platform);
Array( 0 => 'CREATE TABLE users ( id INTEGER NOT NULL, name VARCHAR(32) NOT NULL, PRIMARY KEY("id") )')
sábado, 26 de junho de 2010
Doctrine\DBAL
Removendo um schema:// obtém as queries para remover o schema em segurança.$queries = $schema->toDropSql($platform);
Array( 0 => 'DROP TABLE users')
Faz o inverso que ->toSql() faz
sábado, 26 de junho de 2010
Doctrine\DBAL
Comparando schemas:$platform = $em->getConnection()->getDatabasePlatform();
$fromSchema = new \Doctrine\DBAL\Schema\Schema();$table = $fromSchema->createTable("users"); $table->addColumn("id", "integer", array("unsigned" => true));$table->addColumn("name", "string", array("length" => 32));$table->setPrimaryKey(array("id"));
sábado, 26 de junho de 2010
Doctrine\DBAL
Comparando schemas:$platform = $em->getConnection()->getDatabasePlatform();
$toSchema = new \Doctrine\DBAL\Schema\Schema(); $table = $toSchema->createTable("users"); $table->addColumn("id", "integer", array("unsigned" => true));$table->addColumn("name", "string", array("length" => 32));$table->addColumn("email", "string", array("length" => 255));$table->setPrimaryKey(array("id"));
sábado, 26 de junho de 2010
Doctrine\DBAL
Comparando schemas:$platform = $em->getConnection()->getDatabasePlatform();
$comparator = new \Doctrine\DBAL\Schema\Comparator(); $schemaDiff = $comparator->compare($fromSchema, $toSchema);
// queries para alterar de um schema para outro.$queries = $schemaDiff->toSql($platform);
Array( 0 => 'ALTER TABLE users ADD email VARCHAR(255) NOT NULL')
sábado, 26 de junho de 2010
Performance em Inserções
Inserindo 20 entradas com Doctrine 2:for ($i = 0; $i < 20; $i++) { $user = new User(); $user->name = 'Guilherme Blanco'; $em->persist($user);}
$start = microtime(0);$em->flush();$end = microtime(0);
echo $end - $start;
sábado, 26 de junho de 2010
Performance em Inserções
Inserindo 20 entradas com código PHP “crú”:$start = microtime(0);
for ($i = 0; $i < 20; $i++) { mysql_query( "INSERT INTO users (name) VALUES ('Guilherme Blanco')", $db_link );}
$end = microtime(0);
echo $end - $start;
sábado, 26 de junho de 2010
Performance em Inserções
Sem palhaçada aqui! =PQual deles vocês acham que é mais rápido? Doctrine 2
Tempo: 0.0094 segundos Código PHP
Tempo: 0.0165 segundos
PQP?!?! Doctrine + rápido que código PHP puro? Provê muito menos, não provê recursos, sem abstração! A resposta é TRANSAÇÃO!
Doctrine 2 gerencia nossas transações e executa todos os comandos de forma eficiente numa única.
sábado, 26 de junho de 2010
Performance em Inserções
Doctrine 2 *NÃO É* mais rápido que código PHP puro
Desenvolvedores passam por cima de pequenos detalhes e podem causar problemas significantes de performance!
sábado, 26 de junho de 2010
Performance em Inserções
Inserindo 20 entradas com código PHP “crú”:$start = microtime(0);
mysql_query("START TRANSACTION", $db_link);
for ($i = 0; $i < 20; $i++) { mysql_query( "INSERT INTO users (name) VALUES ('Guilherme Blanco')", $db_link );}
mysql_query("COMMIT", $db_link);
$end = microtime(0);
echo $end - $start;
sábado, 26 de junho de 2010
Performance em Inserções
Informações finais de performance... Doctrine 2
Tempo: 0.0094 segundos Código PHP
Tempo: 0.0165 segundos Código PHP (revisitado)
Tempo: 0.0028 segundos
Você pode ler mais sobre isto no blog do Doctrine http://www.doctrine-project.org/blog/transactions-and-performance
sábado, 26 de junho de 2010
Doctrine\ORM
O que aprendemos com Doctrine 1? Camada de Persistência != Modelo de Domínio Foco no propósito chave, a Camada de Persistência “You’re doing it wrong!” Extingüir a mágica
sábado, 26 de junho de 2010
Doctrine\ORM
Comparação de performance Hidratar 5000 registros
Doctrine 1.2: 4.3 segundos Doctrine 2.0-DEV: 1.4 segundos
Hidratar 10000 registros Doctrine 2.0-DEV: 3.5 segundos
Duas vezes mais registros e ainda assim mais rápido que o Doctrine 1!
sábado, 26 de junho de 2010
Doctrine\ORM
Por que é mais rápido? Otimizações do PHP 5.3!
30% menos recursos, 20% mais rápido 5.3-DEV (lazy bucket alloc, interned strings, runtime cache),
Doctrine 2 pode rodar 50% mais rápido! Melhor algoritmo de hidratação Ordenação Topológica Entidades enxutas Aspectos mágicos do Doctrine 1 extintos
sábado, 26 de junho de 2010
Doctrine\ORM
Por que extingüir a mágica? Eliminar o fator PQP/minuto
Difícil de debugar Casos extremos são difíceis de corrigir Casos extremos são difíceis de se contornar
Tudo funciona até você sair fora da caixa
...e a mágina é lenta! Eu posso provar, olha! __set é ~87% mais lento que um set normal __get é ~150% mais lento que um get normal
sábado, 26 de junho de 2010
Doctrine\ORM
Como extingüir a mágica? Nós chamamos de POO!
Composição Herança Agregação Polimorfismo Encapsulamento etc
sábado, 26 de junho de 2010
Doctrine\ORM
DataMapper ao invés de ActiveRecord
Densamente inspirado em JSR-317/JPA v2.0
Java... QUÊ?!?! #$@&*! PHP ainda peca pela falta de padronização PHP Standards Group pode nos socorrer?!
Versão final 2.0.0 esperada para Setembro
sábado, 26 de junho de 2010
Doctrine\ORM
Entidades Classe PHP regular Objeto persistente de domínio enxuto Não necessita extender uma classe base! Não pode ser final ou conter métodos final Duas entidades na hierarquia de classes não pode
mapear uma propriedade com o mesmo nome Classes concretas e abstratas podem ser Entidades Entidades podem extender classes não-entidades bem
como classes entidades Classes não-entidade podem extender classes entidades
sábado, 26 de junho de 2010
Doctrine\ORMnamespace Entity;
/** * @Entity * @Table(name="users") */class User { /** * @Id @GeneratedValue * @Column(type="integer") */ protected $id;
/** * @Column(type="string", length=32) */ protected $name;
// ... getters and setters}
sábado, 26 de junho de 2010
Doctrine\ORMEntity\User: type: entity table: users id: id: type: integer generator: strategy: AUTO fields: name: type: string length: 32
sábado, 26 de junho de 2010
Doctrine\ORM<?xml version="1.0" encoding="UTF-8"?><doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mappinghttp://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="Entity\User" table="users"> <id name="id" type="integer"> <generator strategy="AUTO"/> </id> <field name="name" type="string" length="50"/> </entity></doctrine-mapping>
sábado, 26 de junho de 2010
Doctrine\ORM
Mapeamento de Colunas type length scale, precision nullable unique name (DB) options columnDefinition
/** * @Column(type="string", length=32, unique=true) */protected $foo;
sábado, 26 de junho de 2010
Doctrine\ORM
Campos identificadores Suporta diferentes estratégias:
AUTO SEQUENCE TABLE NONE
/** * @Id @GeneratedValue(strategy="AUTO") * @Column(type="integer") */protected $id;
sábado, 26 de junho de 2010
Doctrine\ORM
Campos de associação OneToOne
/** @OneToOne(targetEntity="Shipping") */private $shipping;
OneToMany ManyToOne ManyToMany
/** * @ManyToMany(targetEntity="Group") * @JoinTable(name="users_groups", joinColumns={ * @JoinColumn(name="user_id", referencedColumnName="id") * }, inverseJoinColumns={ * @JoinColumn(name="group_id", referencedColumnName="id") * }) */private $groups;
sábado, 26 de junho de 2010
Doctrine\ORM
Herança Concrete Table Inheritance
Sem colunas irrelevantes Sem problemas de colisão
Difícil para lidar com chaves primárias Pesquisa na superclasse significa pesquisar em todas as
tabelas (muitas queries ou umjoin maluco) Refatoração nos campos significa um update em algumas ou
todas as tabelas
sábado, 26 de junho de 2010
Doctrine\ORM/** @MappedSuperclass */class MappedSuperclassBase { /** @Column(type="string") */ protected $mapped;
/** * @OneToOne(targetEntity="MappedSuperclassRelated") * @JoinColumn(name="related_id", referencedColumnName="id") */ protected $related;}
/** @Entity @Table(name="users") */class User extends MappedSuperclassBase { /** @Id @Column(type="integer") */ protected $id;
/** @Column(type="string", length=32) */ protected $name;}
sábado, 26 de junho de 2010
Doctrine\ORMCREATE TABLE users ( mapped TEXT NOT NULL, id INTEGER NOT NULL, name TEXT NOT NULL, related_id INTEGER DEFAULT NULL, PRIMARY KEY(id));
sábado, 26 de junho de 2010
Doctrine\ORM
Herança Single Table Inheritance
Somente uma tabela na base de dados Sem joins Refatoração de campos não muda o schema da tabela
Disperdício de espaço na base de dados Muitos locks devido aos inúmeros acessos Sem duplicação de nome de campos com diferentes significados
sábado, 26 de junho de 2010
Doctrine\ORMnamespace MyProject\Entity;
/** * @Entity * @InheritanceType("SINGLE_TABLE") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({ * "user" = "User", "employee" = "Employee" * }) */class User { // ...}
/** @Entity */class Employee extends User { // ...}
sábado, 26 de junho de 2010
Doctrine\ORM
Herança Class Table Inheritance
Fácil de entender Espaço na tabela é otimizado devido à normalização Relacionamento direto entre o Modelo de Domínio e a base
Muitos joins Refatoração de campos precisa de um update no schema Tabela supertipo é muito acessado, pode estar em lock
sábado, 26 de junho de 2010
Doctrine\ORMnamespace MyProject\Entity;
/** * @Entity * @InheritanceType("JOINED") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({ * "user" = "User", "employee" = "Employee" * }) */class User { // ...}
/** @Entity */class Employee extends User { // ...}
sábado, 26 de junho de 2010
Doctrine\ORM
Proxies Carga-tardia dos dados da Entidade Provê a possibilidade de obter uma referência à
Entidade sem acesso à base de dados Pode ser gerado em tempo de execução ou via
ferramenta de linha de comando
$proxyUser = $em->getReference("User", 1);
sábado, 26 de junho de 2010
Doctrine\ORM
EntityManager Ponto central da funcionalidade ORM Aplica a estratégia de Transaction Write Behind que
atrasa a execução de comandos SQL ...isto significa, eficiência! ...e também significa que os locks de escrita são
rapidamente liberados!
Internamante, ele usa UnitOfWork para manter informações de estado dos objetos
sábado, 26 de junho de 2010
Doctrine\ORMinterface \Doctrine\ORM\EntityManager { // Transaction API
/* Starts a transaction on the underlying database connection. */ function beginTransaction();
/* Commits a transaction on underlying database connection. */ function commit();
/* Flushes all changes to queued objects to the database. */ function flush();
/* Performs a rollback on the underlying database connection. */ function rollback();
/* Executes a function in a transaction. */ function transactional(\Closure $func);
// ...
sábado, 26 de junho de 2010
Doctrine\ORM // Query API
/* Creates a new Query object. */ function createQuery($dql);
/* Creates a native SQL query. */ function createNativeQuery( $sql, \Doctrine\ORM\Query\ResultSetMapping $rsm );
/* Create a QueryBuilder instance. */ function createQueryBuilder();
/* Finds an Entity by its identifier. */ function find($entityName, $identifier, $lockMode = LockMode::NONE, $lockVersion = null);
/* Gets a reference to the entity identified by the given type and identifier without actually loading it. */ function getReference($entityName, $identifier);
// ...sábado, 26 de junho de 2010
Doctrine\ORM // Object Manipulation API
/* Tells EntityManager to make instance managed and persistent. */ function persist($entity);
/* Removes an entity instance. */ function remove($entity);
/* Refresh state of entity from database, overrides changes. */ function refresh($entity);
/* Detaches an entity from the EntityManager. */ function detach($entity);
/* Merges state of detached entity into persistence context. */ function merge($entity);
// ...
sábado, 26 de junho de 2010
Doctrine\ORM // Repository, Configuration, EventManager, etc
/* Gets the EventManager used by the EntityManager. */ function getEventManager();
/* Gets the Configuration used by the EntityManager. */ function getConfiguration();
/* Gets the repository for an entity class. */ function getRepository($entityName);
/* Returns the metadata for a class. */ function getClassMetadata($className);
/* Gets database connection object used by the EntityManager. */ function getConnection();}
sábado, 26 de junho de 2010
Doctrine\ORM
Trabalhando com Entidades no EntityManager Criando o EntityManager
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataCacheImpl($cacheDriver);$config->setQueryCacheImpl($cacheDriver);
$config->setProxyDir("/path/to/MyProject/Proxies");$config->setProxyNamespace("MyProject\Proxies");
$connectionOptions = array( "driver" => "pdo_sqlite", "path" => "database.sqlite");
// Creating the EntityManager$em = \Doctrine\ORM\EntityManager::create( $connectionOptions, $config);
sábado, 26 de junho de 2010
Doctrine\ORM
Trabalhando com Entidades no EntityManager Persistindo Entidades
try { $em->transactional(function ($em) { $user = new \MyProject\Entity\User(); $user->name = "Guilherme Blanco";
$em->persist($user); });} catch (\Exception $e) { // ...}
sábado, 26 de junho de 2010
Doctrine\ORM
Trabalhando com Entidades no EntityManager Atualizando Entidades
try { $em->transactional(function ($em) { $user = $em->find("MyProject\Entity\User", 1); $user->name = "Benjamin Eberlei";
$em->persist($user); });} catch (\Exception $e) { // ...}
sábado, 26 de junho de 2010
Doctrine\ORM
Trabalhando com Entidades no EntityManager Removendo Entidades
try { $em->transactional(function ($em) { $user = $em->getReference("MyProject\Entity\User", 1); $em->remove($user); });} catch (\Exception $e) { // ...}
sábado, 26 de junho de 2010
Doctrine\ORM
Doctrine Query Language (DQL) Implementação de uma OQL Fortemente influenciada por Hibernate QL Top-down recursive descent parser LL(*), construindo
uma árvore de abstração sintática (AST) AST é então usada para gerar SQL dependente
$query = $em->createQuery( "SELECT u FROM MyProject\Entity\User u");$users = $query->execute();
sábado, 26 de junho de 2010
Doctrine\ORM
Native Query Possibilita voltar ao poder da SQL sem perder a
habilidade de hidratar seus dados na sua Entidade$rsm = new \Doctrine\ORM\Query\ResultSetMapping();$rsm->addEntityResult("MyProject\Entity\User", "u");$rsm->addFieldResult("u", "id", "id");$rsm->addFieldResult("u", "name", "name");
$query = $em->createNativeQuery( "SELECT id, name FROM users WHERE username = ?", $rsm);$query->setParameter(1, "guilhermeblanco");
$users = $query->getResult();
sábado, 26 de junho de 2010
Doctrine\ORM
QueryBuilder Implementação de um Builder Construção e execução são separadas QueryBuilder não pode ser executada; ao invés disso,
obtenha uma instância de Query e execute-a
$qb = $em->createQueryBuilder() ->select("u") ->from("MyProject\Entity\User", "u");$users = $qb->getQuery()->execute();
sábado, 26 de junho de 2010
Doctrine\ORM
Doctrine suporta diferentes níveis de cache Metadata cache
$config->setMetadataCacheImpl($cacheDriver);
Query cache$config->setQueryCacheImpl($cacheDriver);
Result cache$config->setResultCacheImpl($cacheDriver);
$query = $em->createQuery( "SELECT u FROM MyProject\Entity\User u");$query->useResultCache(true, 3600, "my_custom_name");
sábado, 26 de junho de 2010
Doctrine\ORM
Console Usa o componente Symfony 2 Console Auxilia a desenvolver com Doctrine Tarefas disponíveis em todos os pacotes
$helperSet = $cli->getHelperSet();$helperSet->set( new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper( $em->getConnection() ), 'db');$helperSet->set( new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper( $em ), 'em');
$cli->addCommands(array(...));
sábado, 26 de junho de 2010
Doctrine\ORM
Comandos disponíveis: \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand \Doctrine\DBAL\Tools\Console\Command\ImportCommand \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand \Doctrine\ORM\Tools\Console\Command\RunDqlCommand
sábado, 26 de junho de 2010
Future
DBAL QueryBuilder Concluir o driver MSSQL Server
DQL Suporte a TYPE() Adicionar múltiplos FROM Embedded Values
ODM Extrair a interface de DocumentManager Estabilizar o driver de MongoDB Implementar outros drivers (CouchDB, SimpleDB, ...)
sábado, 26 de junho de 2010
Questions?
Guilherme Blanco Informações de contato:
@guilhermeblanco
http://www.facebook.com/guilhermeblanco
+55 16 9215.8480
OBRIGADO PELA PACIÊNCIA!!! =)
sábado, 26 de junho de 2010