Doctrine 2
Enterprise Persistence Layer for PHP
Guilherme Blanco, Yahoo!
quarta-feira, 2 de junho de 2010
Who am I?
10+ years web developer
Open Source evangelist
Works for Yahoo!
Contributes to... ...Doctrine ...Zend Framework ...Symfony ...PHP etc
Likes to sing and also fish on spare time! =)
quarta-feira, 2 de junho de 2010
Who am I?
http://www.twitter.com/guilhermeblanco
http://www.facebook.com/guilhermeblanco
quarta-feira, 2 de junho de 2010
Doctrine 2
quarta-feira, 2 de junho de 2010
Doctrine 2
PHP 5.3+
100% code rewritten
Fully namespaced code
quarta-feira, 2 de junho de 2010
Doctrine 2
Tools used: phpUnit Unit testing Phing Packaging and distribution Symfony Components
YAMLConsole
Sismo Continuous Integration GIT Source version control JIRA Issue tracking and management Trac Timeline, source code & changeset viewer
quarta-feira, 2 de junho de 2010
Doctrine 2
Three main packages: Common
DBAL
ORM
quarta-feira, 2 de junho de 2010
Doctrine\Common
[email protected]:doctrine/common.git
Cache Drivers
quarta-feira, 2 de junho de 2010
Doctrine\Common\Cache
Supported Drivers: 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();
quarta-feira, 2 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);
}
quarta-feira, 2 de junho de 2010
Doctrine\Common
[email protected]:doctrine/common.git
Cache Drivers
Class Loader
quarta-feira, 2 de junho de 2010
Doctrine\Common\ClassLoader
Implements PSR #0 PSR = PHP Standards Recommendation
Technical Interoperability between libraries Symfony, Zend Framework, Doctrine, Agavi, PEAR2/Pyrus,
Lithium, Flow3, Solar, etc
Possible merge in PHP core: SplClassLoader http://wiki.php.net/rfc/splclassloader
quarta-feira, 2 de junho de 2010
Doctrine\Common\ClassLoader
Usage:
require_once '/path/to/lib/Doctrine/Common/ClassLoader.php';
$doctrineClassLoader = new \Doctrine\Common\ClassLoader( 'Doctrine', '/path/to/lib/Doctrine');
$doctrineClassLoader->register();
quarta-feira, 2 de junho de 2010
Doctrine\Common
[email protected]:doctrine/common.git
Cache Drivers
Class Loader
Collections
quarta-feira, 2 de junho de 2010
Doctrine\Common\Collections
Solution inspired in java.util.Collection interface
Plain PHP arrays are hard to manipulate
..but custom array implementations are not compatible with array_* functions
Heavily usage of Closures
User-land SplArray Where are the PHP devs?
quarta-feira, 2 de junho de 2010
Doctrine\Common
[email protected]:doctrine/common.git
Cache Drivers
Class Loader
Collections
Lexer
Annotations Parser
quarta-feira, 2 de junho de 2010
Doctrine\Common\Annotations
Java like Annotations
Define metadata information in classes
Reusable and highly extendable
Suppress missing PHP functionality Again, where are the PHP devs? RFC already written: http://wiki.php.net/rfc/annotations
quarta-feira, 2 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
quarta-feira, 2 de junho de 2010
Doctrine\Common\Annotations
Creating Annotations classes:
final class \Doctrine\ORM\Mapping\Entity extends \Doctrine\Common\Annotations\Annotation { public $repositoryClass;}
Using Annotations:
namespace MyProject\Entity;
/** * @Entity(repositoryClass="Repository\UserRepository") */class User { // ... }
quarta-feira, 2 de junho de 2010
Doctrine\Common\Annotations
Reading 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;
quarta-feira, 2 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);}
quarta-feira, 2 de junho de 2010
Doctrine\DBAL
[email protected]:doctrine/dbal.git
Database Abstraction Layer built at the top of PDO and proprietary drivers
Supported drivers: DB2 Microsoft SQL Server (pdo_sqlsrv & sqlsrv) MySQL PostgreSQL Oracle SQLite
quarta-feira, 2 de junho de 2010
Doctrine\DBAL
Improved API for Database introspection and schema management
Hopefully it can be a defacto standard DBAL for PHP 5.3 in the future, like MDB2 for PEAR1
Inspired in ezcDatabase, MDB2 and Zend_Db
Maybe we can make this happen for PEAR2
quarta-feira, 2 de junho de 2010
Doctrine\DBALinterface \Doctrine\DBAL\Connection { // Data manipulation API
/* Executes an SQL DELETE statement on a table. */ function delete($tableName, array $identifier);
/* Executes an SQL UPDATE statement on a table. */ function update($tableName, array $data, array $identifier);
/* Inserts a table row with specified data. */ function insert($tableName, array $data);
/* Prepares an SQL statement. Returns a DBAL\Statement */ function prepare($statement);
/* Applies a SQL statement and return # of affected rows. */ function exec($statement);
// ...
quarta-feira, 2 de junho de 2010
Doctrine\DBAL // Transaction API
/* Returns the current transaction nesting level. */ function getTransactionNestingLevel();
/* Executes a function in a transaction. */ function transactional(\Closure $func);
/* Starts a transaction by suspending auto-commit mode. */ function beginTransaction();
/* Commits the current transaction. */ function commit();
/* Cancel any database changes done during current transaction. */ function rollback();
/* Check if current transaction is marked for rollback only. */ function isRollbackOnly();
// ...
quarta-feira, 2 de junho de 2010
Doctrine\DBAL // Data fetching API
/* Executes a SQL query and returns first row as an assoc array. */ function fetchAssoc($statement, array $params = array());
/* Executes a SQL query and returns first row as a numeric array. */ function fetchArray($statement, array $params = array());
/* Executes a SQL query and returns first column value of result. */ function fetchColumn( $statement, array $params = array(), $colnum = 0 );
/* Executes a SQL query and returns the result as an assoc array. */ function fetchAll($sql, array $params = array());}
quarta-feira, 2 de junho de 2010
Doctrine\DBAL\Types
Centralized point to convert values From Database to PHP From PHP to Database
Database agnostic
Accessing specific DB dialect called Platform
Extendable
quarta-feira, 2 de junho de 2010
Doctrine\DBAL\Types
New DataType is just implement an abstract class: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();}
quarta-feira, 2 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"; }}
quarta-feira, 2 de junho de 2010
Doctrine\DBAL\Types
Finally, make Doctrine know about your DataType:\Doctrine\DBAL\Types\Type::addType( "my-object", "\MyProject\DataTypes\MyObjectType");
Then you can use it in your Entities!/** * @Entity * @Table(name="files") */class File { // ...
/** * @Column(type="my-object") */ protected $content;}
quarta-feira, 2 de junho de 2010
Doctrine\DBAL
Creating a 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"));
// get queries to create this schema.$queries = $schema->toSql($platform);
Array( 0 => 'CREATE TABLE users ( id INTEGER NOT NULL, name VARCHAR(32) NOT NULL, PRIMARY KEY("id") )')
quarta-feira, 2 de junho de 2010
Doctrine\DBAL
Deleting a schema:// get queries to safely delete the schema.$queries = $schema->toDropSql($platform);
Array( 0 => 'DROP TABLE users')
It does the reverse of what ->toSql() does
quarta-feira, 2 de junho de 2010
Doctrine\DBAL
Comparing 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"));
quarta-feira, 2 de junho de 2010
Doctrine\DBAL
Comparing 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"));
quarta-feira, 2 de junho de 2010
Doctrine\DBAL
Comparing schemas:$platform = $em->getConnection()->getDatabasePlatform();
$comparator = new \Doctrine\DBAL\Schema\Comparator(); $schemaDiff = $comparator->compare($fromSchema, $toSchema);
// queries to get from one to another schema.$queries = $schemaDiff->toSql($platform);
Array( 0 => 'ALTER TABLE users ADD email VARCHAR(255) NOT NULL')
quarta-feira, 2 de junho de 2010
Insert Performance
Inserting 20 entries with 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;
quarta-feira, 2 de junho de 2010
Insert Performance
Inserting 20 entries with raw PHP code:$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;
quarta-feira, 2 de junho de 2010
Insert Performance
We are not kidding here! =PWhich one do you think it is faster? Doctrine 2
Took: 0.0094 seconds PHP code
Took: 0.0165 seconds
WTH?!?! Doctrine 2 is faster than raw PHP? It does a lot less, provides no features, no abstraction! Answer is TRANSACTIONS!
Doctrine 2 manages our transactions and efficiently executes all inserts in a single.
quarta-feira, 2 de junho de 2010
Insert Performance
Doctrine 2 *IS NOT* faster than raw PHP code
Simple developers oversights can cause significant performance problems!
quarta-feira, 2 de junho de 2010
Insert Performance
Inserting 20 entries with raw PHP code (revisited):$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;
quarta-feira, 2 de junho de 2010
Insert Performance
Final performance information... Doctrine 2
Took: 0.0094 seconds PHP code
Took: 0.0165 seconds PHP code (revisited)
Took: 0.0028 seconds
You can read more about this on Doctrine Blog http://www.doctrine-project.org/blog/transactions-and-performance
quarta-feira, 2 de junho de 2010
Doctrine\ORM
What have we learned from Doctrine 1? Persistence Layer != Domain Model Focus on our key purpose, the Persistence Layer “You’re doing it wrong!” Kill magic
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Performance comparison Hydrating 5000 records
Doctrine 1.2: 4.3 seconds Doctrine 2.0-DEV: 1.4 seconds
Hydrating 10000 records Doctrine 2.0-DEV: 3.5 seconds
Twice records and still faster than Doctrine 1!
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Why is it faster? PHP 5.3 optimizations!
30% less resources usage, 20% faster 5.3-DEV (lazy bucket alloc, interned strings, runtime cache),
Doctrine 2 can run 50% faster! Better Hydration algorithm Topological Sorting Slim Entities Killed magic aspects of Doctrine 1
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Why kill magic? Eliminate the WTF/minute (WTF factor)
Hard to debug Edge cases are hard to fix Edge cases are hard to workaround
Everything works until you go outside the box
...and magic is slow! I can prove it! __set is ~87% slower than normal set __get is ~150% slower than normal get
quarta-feira, 2 de junho de 2010
Doctrine\ORM
How we kill magic? We call it OOP!
Object Composition Inheritance Aggregation Containment Encapsulation etc
quarta-feira, 2 de junho de 2010
Doctrine\ORM
DataMapper instead of ActiveRecord
Heavily inspired by JSR-317, a.k.a. JPA v2.0
Java... WHAT?!?! #$@&*! PHP still lacks of standards PHP Standards Group can rescue us?!
Final 2.0.0 version expected for September 1st
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Entities Regular PHP class Lightweight persistent domain object Do not extend any base class! Cannot be final or contain final methods Two entities in a hierarchy of classes can not map
property with the same name Abstract and concrete classes can be Entities Entities may extend non-entity classes as well as entity
classes Non-entity classes may also extend entity classes
quarta-feira, 2 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}
quarta-feira, 2 de junho de 2010
Doctrine\ORMEntity\User: type: entity table: users id: id: type: integer generator: strategy: AUTO fields: name: type: string length: 32
quarta-feira, 2 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>
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Column mapping type length scale, precision nullable unique name (DB) options columnDefinition
/** * @Column(type="string", length=32, unique=true) */protected $foo;
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Identifier fields Supports different strategies:
AUTO SEQUENCE TABLE NONE
/** * @Id @GeneratedValue(strategy="AUTO") * @Column(type="integer") */protected $id;
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Association fields 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;
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Inheritance Concrete Table Inheritance
No irrelevant columns No locking problems
Difficult to deal with Primary Keys No relations in base class Search on superclass means search in all tables (too much
queries or a weird join) Refactoring of fields means update a few or all table
quarta-feira, 2 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;}
quarta-feira, 2 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));
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Inheritance Single Table Inheritance
Only one table on database No joins Refactoring of fields do not change DB schema
Waste of space on database Too many locks due to many accesses No duplicated name of fields with different meaning
quarta-feira, 2 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 { // ...}
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Inheritance Class Table Inheritance
Easy to understand DB space is optimized due to normalization Direct relationship between Domain Model and database
Too many joins Refactoring of fields need a database schema update Supertype table accessed a lot, may be in lock mode
quarta-feira, 2 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 { // ...}
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Proxies Lazy-load Entity data Provide the possibility to get an Entity reference
without database access Can be generated on-the-fly (during script execution)
or via a Console tool
$proxyUser = $em->getReference("User", 1);
quarta-feira, 2 de junho de 2010
Doctrine\ORM
EntityManager Central point of ORM functionality Employes Transaction Write Behind strategy that
delays executions of SQL statements ...this means, efficiency! ...and also means that write locks are quickly released!
Internally, it uses a UnitOfWork to keep track of your objects state
quarta-feira, 2 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);
// ...
quarta-feira, 2 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);
// ...quarta-feira, 2 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);
// ...
quarta-feira, 2 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();}
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Working with Entities in EntityManager Creating an 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);
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Working with Entities in EntityManager Persisting Entities
try { $em->transactional(function ($em) { $user = new \MyProject\Entity\User(); $user->name = "Guilherme Blanco";
$em->persist($user); });} catch (\Exception $e) { // ...}
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Working with Entities in EntityManager Updating Entities
try { $em->transactional(function ($em) { $user = $em->find("MyProject\Entity\User", 1); $user->name = "Benjamin Eberlei";
$em->persist($user); });} catch (\Exception $e) { // ...}
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Working with Entities in EntityManager Deleting Entities
try { $em->transactional(function ($em) { $user = $em->getReference("MyProject\Entity\User", 1); $em->remove($user); });} catch (\Exception $e) { // ...}
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Doctrine Query Language (DQL) Implementation of an OQL Heavily influenced by Hibernate QL Parsed by a top-down recursive descent parser LL(*),
constructing an abstract syntax tree (AST) AST is then used to generate vendor dependent SQL
$query = $em->createQuery( "SELECT u FROM MyProject\Entity\User u");$users = $query->execute();
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Native Query Allow you the possibility to fallback to the power of
SQL without losing the ability to hydrate the data to your Entities
$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();
quarta-feira, 2 de junho de 2010
Doctrine\ORM
QueryBuilder Builder implementation Building and execution are separated QueryBuilder cannot be executed; instead, get the
Query instance from it and execute
$qb = $em->createQueryBuilder() ->select("u") ->from("MyProject\Entity\User", "u");$users = $qb->getQuery()->execute();
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Doctrine supports different cache levels 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");
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Console Uses Symfony 2 Console component Help developing with Doctrine Tasks available in all packages
$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(...));
quarta-feira, 2 de junho de 2010
Doctrine\ORM
Available Commands: \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
quarta-feira, 2 de junho de 2010
Future
DBAL QueryBuilder Finish MSSQL Server driver
DQL Support for TYPE() Add multiple FROM Entities support Embedded Values
ODM Extract DocumentManager interface Stabilize the MongoDB driver Implement other drivers (CouchDB, SimpleDB, ...)
quarta-feira, 2 de junho de 2010
Questions?
Guilherme Blanco Contact Info:
@guilhermeblanco
http://www.facebook.com/guilhermeblanco
+55 16 9215.8480
THANK YOU FOR YOUR PATIENCE!!! =)
quarta-feira, 2 de junho de 2010