1. Guilherme Blanco, Yahoo!
Doctrine 2
Camada de Persistência para PHP 5.3+
sábado, 26 de junho de 2010
2. 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
3. Quem sou eu?
http://www.twitter.com/guilhermeblanco
http://www.facebook.com/guilhermeblanco
sábado, 26 de junho de 2010
5. Doctrine 2
PHP 5.3+
100% do código reescrito
Código totalmente em namespaces
sábado, 26 de junho de 2010
6. Doctrine 2
Ferramentas usadas:
phpUnit Unit test
Phing Pacotes e distribuição
Symfony Components
YAML
Console
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
7. Doctrine 2
Três principais pacotes:
Common
DBAL
ORM
sábado, 26 de junho de 2010
8. DoctrineCommon
git@github.com:doctrine/common.git
Cache Drivers
sábado, 26 de junho de 2010
9. DoctrineCommonCache
Drivers Suportados:
APCCache
$cacheDriver = new DoctrineCommonCacheApcCache();
MemcacheCache
$memcache = new Memcache();
$memcache->addServer('memcache_host', 11211);
$cacheDriver = new DoctrineCommonCacheMemcacheCache();
$cacheDriver->setMemcache($memcache);
XcacheCache
$cacheDriver = new DoctrineCommonCacheXcacheCache();
sábado, 26 de junho de 2010
10. DoctrineCommonCache
Cache Drivers Interface:
interface DoctrineCommonCacheCache {
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
11. DoctrineCommon
git@github.com:doctrine/common.git
Cache Drivers
Class Loader
sábado, 26 de junho de 2010
12. DoctrineCommonClassLoader
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
13. DoctrineCommonClassLoader
Como usar:
require_once '/path/to/lib/Doctrine/Common/ClassLoader.php';
$doctrineClassLoader = new DoctrineCommonClassLoader(
'Doctrine', '/path/to/lib/Doctrine'
);
$doctrineClassLoader->register();
sábado, 26 de junho de 2010
14. DoctrineCommon
git@github.com:doctrine/common.git
Cache Drivers
Class Loader
Collections
sábado, 26 de junho de 2010
15. DoctrineCommonCollections
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
16. DoctrineCommon
git@github.com:doctrine/common.git
Cache Drivers
Class Loader
Collections
Lexer
sábado, 26 de junho de 2010
17. DoctrineCommon
git@github.com:doctrine/common.git
Cache Drivers
Class Loader
Collections
Lexer
Annotations Parser
sábado, 26 de junho de 2010
18. DoctrineCommonAnnotations
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
20. DoctrineCommonAnnotations
Criando classes de Annotations:
final class DoctrineORMMappingEntity
extends DoctrineCommonAnnotationsAnnotation {
public $repositoryClass;
}
Usando as Annotations:
namespace MyProjectEntity;
/**
* @Entity(repositoryClass="RepositoryUserRepository")
*/
class User {
// ...
}
sábado, 26 de junho de 2010
21. DoctrineCommonAnnotations
Lendo Annotations:
$reader = new DoctrineCommonAnnotationsAnnotationReader(
new DoctrineCommonCacheArrayCache()
);
$reader->setDefaultAnnotationNamespace(
'DoctrineORMMapping'
);
$class = new ReflectionClass('MyProjectEntityUser');
$classAnnotations = $reader->getClassAnnotations($class);
echo $classAnnotations['DoctrineORMMappingEntity']
->repositoryClass;
sábado, 26 de junho de 2010
22. DoctrineCommonAnnotations
interface DoctrineCommonAnnotationsAnnotationReader {
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
23. DoctrineDBAL
git@github.com: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
24. DoctrineDBAL
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
25. DoctrineDBAL
interface DoctrineDBALConnection {
// 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 DBALStatement */
function prepare($statement);
/* Aplica um SQL statement e retorna # linhas afetadas. */
function exec($statement);
// ...
sábado, 26 de junho de 2010
26. DoctrineDBAL
// 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
27. DoctrineDBAL
// 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
28. DoctrineDBALTypes
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
29. DoctrineDBALTypes
Novo tipo é só implementar uma classe abstrata:
interface DoctrineDBALTypesType {
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
30. DoctrineDBAL
class MyProjectDataTypesMyObjectType extends DoctrineDBALTypesType
{
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
31. DoctrineDBALTypes
Finalmente, faça o Doctrine saber sobre seu tipo:
DoctrineDBALTypesType::addType(
"my-object", "MyProjectDataTypesMyObjectType"
);
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
32. DoctrineDBAL
Criando um schema:
$platform = $em->getConnection()->getDatabasePlatform();
$schema = new DoctrineDBALSchemaSchema();
$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
33. DoctrineDBAL
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
34. DoctrineDBAL
Comparando schemas:
$platform = $em->getConnection()->getDatabasePlatform();
$fromSchema = new DoctrineDBALSchemaSchema();
$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
35. DoctrineDBAL
Comparando schemas:
$platform = $em->getConnection()->getDatabasePlatform();
$toSchema = new DoctrineDBALSchemaSchema();
$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
36. DoctrineDBAL
Comparando schemas:
$platform = $em->getConnection()->getDatabasePlatform();
$comparator = new DoctrineDBALSchemaComparator();
$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
37. 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
38. 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
39. Performance em Inserções
Sem palhaçada aqui! =P
Qual 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
40. 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
41. 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
42. 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
43. DoctrineORM
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
44. DoctrineORM
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
45. DoctrineORM
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
46. DoctrineORM
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
47. DoctrineORM
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
48. DoctrineORM
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
49. DoctrineORM
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
50. DoctrineORM
namespace 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
51. DoctrineORM
EntityUser:
type: entity
table: users
id:
id:
type: integer
generator:
strategy: AUTO
fields:
name:
type: string
length: 32
sábado, 26 de junho de 2010
56. DoctrineORM
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
57. DoctrineORM
/** @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
58. DoctrineORM
CREATE 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
59. DoctrineORM
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
60. DoctrineORM
namespace MyProjectEntity;
/**
* @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
61. DoctrineORM
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
62. DoctrineORM
namespace MyProjectEntity;
/**
* @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
63. DoctrineORM
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
64. DoctrineORM
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
65. DoctrineORM
interface DoctrineORMEntityManager {
// 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
66. DoctrineORM
// Query API
/* Creates a new Query object. */
function createQuery($dql);
/* Creates a native SQL query. */
function createNativeQuery(
$sql, DoctrineORMQueryResultSetMapping $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
67. DoctrineORM
// 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
68. DoctrineORM
// 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
69. DoctrineORM
Trabalhando com Entidades no EntityManager
Criando o EntityManager
$config = new DoctrineORMConfiguration();
$config->setMetadataCacheImpl($cacheDriver);
$config->setQueryCacheImpl($cacheDriver);
$config->setProxyDir("/path/to/MyProject/Proxies");
$config->setProxyNamespace("MyProjectProxies");
$connectionOptions = array(
"driver" => "pdo_sqlite",
"path" => "database.sqlite"
);
// Creating the EntityManager
$em = DoctrineORMEntityManager::create(
$connectionOptions, $config
);
sábado, 26 de junho de 2010
70. DoctrineORM
Trabalhando com Entidades no EntityManager
Persistindo Entidades
try {
$em->transactional(function ($em) {
$user = new MyProjectEntityUser();
$user->name = "Guilherme Blanco";
$em->persist($user);
});
} catch (Exception $e) {
// ...
}
sábado, 26 de junho de 2010
71. DoctrineORM
Trabalhando com Entidades no EntityManager
Atualizando Entidades
try {
$em->transactional(function ($em) {
$user = $em->find("MyProjectEntityUser", 1);
$user->name = "Benjamin Eberlei";
$em->persist($user);
});
} catch (Exception $e) {
// ...
}
sábado, 26 de junho de 2010
72. DoctrineORM
Trabalhando com Entidades no EntityManager
Removendo Entidades
try {
$em->transactional(function ($em) {
$user = $em->getReference("MyProjectEntityUser", 1);
$em->remove($user);
});
} catch (Exception $e) {
// ...
}
sábado, 26 de junho de 2010
73. DoctrineORM
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 MyProjectEntityUser u"
);
$users = $query->execute();
sábado, 26 de junho de 2010
74. DoctrineORM
Native Query
Possibilitavoltar ao poder da SQL sem perder a
habilidade de hidratar seus dados na sua Entidade
$rsm = new DoctrineORMQueryResultSetMapping();
$rsm->addEntityResult("MyProjectEntityUser", "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
75. DoctrineORM
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("MyProjectEntityUser", "u");
$users = $qb->getQuery()->execute();
sábado, 26 de junho de 2010
76. DoctrineORM
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 MyProjectEntityUser u"
);
$query->useResultCache(true, 3600, "my_custom_name");
sábado, 26 de junho de 2010
77. DoctrineORM
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 DoctrineDBALToolsConsoleHelperConnectionHelper(
$em->getConnection()
), 'db'
);
$helperSet->set(
new DoctrineORMToolsConsoleHelperEntityManagerHelper(
$em
), 'em'
);
$cli->addCommands(array(...));
sábado, 26 de junho de 2010
79. 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
80. Questions?
Guilherme Blanco
Informações de contato:
@guilhermeblanco
guilhermeblanco@php.net
http://www.facebook.com/guilhermeblanco
+55 16 9215.8480
OBRIGADO PELA PACIÊNCIA!!! =)
sábado, 26 de junho de 2010