doctrine 2: enterprise persistence layer for php
DESCRIPTION
Doctrine 2 is an object relational mapper (ORM) for PHP 5.3+ that sits on top of a powerful database abstraction layer (DBAL). One of its key features is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL), inspired by Hibernates HQL. This provides developers with a powerful alternative to SQL that maintains flexibility without requiring unnecessary code duplication.TRANSCRIPT
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Doctrine 2Enterprise Persistence Layer for PHP 5.3
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Jonathan H. Wage• Web developer for a decade• Open Source Evangelist• Published Author• Contributes to...• ...Doctrine• ...Symfony• ...and more• Employee of Sensio Labs, the creators of
Symfony
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Jonathan H. Wage• http://www.twitter.com/jwage
• http://www.jwage.com
• http://www.facebook.com/jwage
You can contact Jonathan about Doctrine and Open-Source or for training, consulting, application development, or business related
questions at [email protected]
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
How many have used Doctrine?• Before 1.0?• 1.0?• 1.1?• 1.2?• 2.0?
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Doctrine 1.0• First commit April 13th 2006
• Finished and Released September 1st 2008
• One of the first true ORM implementation for PHP
• First LTS(long term support) release. Maintained until March 1st 2010
• Integrated with many popular frameworks: Symfony, Zend Framework, Code Igniter, etc.
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Doctrine 1.1• Continued evolution of 1.0
• Dozens of small improvements
• Several significant new features
• Too many bug fixes to count
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Doctrine 1.2• Last LTS release of the Doctrine 1.x series
• More bug fixes
• More improvements
• Even more new features
• Scheduled to release this month
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Doctrine 2.0
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Requires PHP 5.3
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Three Main Packages
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Common
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
DBAL
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
ORM
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Fully implements namespaces
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
namespace Doctrine\ORM;
use Doctrine\ORM\Query\Expr, Doctrine\Common\DoctrineException;
/** * This class is responsible for building DQL query strings via an object oriented * PHP interface. * * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link www.doctrine-project.org * @since 2.0 * @version $Revision$ * @author Guilherme Blanco <[email protected]> * @author Jonathan Wage <[email protected]> * @author Roman Borschel <[email protected]> */class QueryBuilder{
Namespaced Code
use Doctrine\ORM\QueryBuilder;
$qb = new QueryBuilder($em);$qb->select('u') ->from('Models\User', 'u') ->orderBy('u.username', 'ASC');
$q = $qb->getQuery();$users = $q->execute();
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Using Namespaces
http://groups.google.com/group/php-standards/web/php-coding-standard-version-2
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Follows PHP 5.3 technical interoperability standards
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
What does this mean?• PHP libraries will finally be 100% technically interoperable
and have optimum autoloading performance
• Symfony 2.0 + Doctrine 2.0 + Zend Framework 2.0
• Load classes from 3 different libraries with one autoloader and one include path
• Share SplClassLoader implementation: http://gist.github.com/221634
• Implement SplClassLoader in C/PHP :)
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Performance of PHP 5.3
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Doctrine 1 and 2 get significant performance increase from 5.3
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
30% Less Memory Used
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
20% Faster
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
What’s my point?
USE PHP 5.3!
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Let the numbers talk
Doctrine 1.14.3 seconds for 5000 records
Doctrine 2.01.4 seconds for 5000 records
Doctrine 2.03.5 seconds for 10000 records
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Doctrine 2 is FAST!
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
The code isn’t that bad on the eyes either
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Quit imposing on my domain model!!
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
The Doctrine 1 Way
class User extends Doctrine_Record{ public function setTableDefinition() { $this->hasColumn('id', 'integer', null, array( 'primary' => true, 'auto_increment' => true ));
$this->hasColumn('username', 'string', 255); }}
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
What is the problem?• We have to extend Doctrine_Record
• It imposes methods, properties, and other junk on our domain model objects
• We have to instantiate a dummy User in order to instantiate the metadata for the model
• Slow, ugly and just not pretty :)
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
The new Doctrine 2 WaySpecify mapping information with doc block
annotations, yaml, xml, or raw PHP code.
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
With Annotations/** * @Entity * @Table(name="user") */class User{ /** * @Id * @Column(type="integer") * @GeneratedValue(strategy="auto") */ public $id;
/** * @Column(type="string", length=255) */ public $username;}
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Entities\User: type: entity table: users fields: id: type: integer id: true generator: strategy: AUTO name: type: string(50)
With YAML
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
<?xml version="1.0" encoding="utf-8"?><doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xsi="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="Entities\User" table="users"> <field name="name" type="string" column="name" length="50" precision="0" scale="0"> <options/> </field> <id name="id" type="integer" column="id"> <generator strategy="AUTO"/> </id> </entity></doctrine-mapping>
With XML
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
With PHPuse Doctrine\ORM\Mapping\ClassMetadataInfo;
$metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_NONE);$metadata->setPrimaryTable(array( 'name' => 'users',));$metadata->mapField(array( 'fieldName' => 'id', 'type' => 'integer', 'id' => true, 'columnName' => 'id',));$metadata->mapField(array( 'fieldName' => 'name', 'type' => 'string', 'length' => '50', 'columnName' => 'name',));$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
No more base class...
...means a clean domain model
User Object( [id] => [username] => jwage)
$user = new \Entities\User();$user->setUsername('jwage');print_r($user);
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Doctrine 2 is heavily decoupledso you can use things standalone
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Use the DBAL without the ORM!
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Database Abstraction Layer• The Doctrine DBAL is a very powerful
project in itself
• Based off of code borrowed from other projects
• PEAR MDB2
• Zend_Db
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Database Abstraction Layer• Using the Doctrine DBAL standalone is a
good option for your PHP projects if a fully featured ORM is not needed
• API for performing DDL statements, executing queries, etc.
• Connect to different types of databases: mysql, sqlite, pgsql, oracle, etc.
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
DBAL Examples
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
$params = array( 'driver' => 'pdo_mysql', 'host' => 'localhost', 'user' => 'root', 'password' => '', 'dbname' => 'doctrine2dbal');$conn = \Doctrine\DBAL\DriverManager::getConnection($params);
Create a Connection to MySQL
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Get the Schema Manager
$sm = $conn->getSchemaManager();
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Schema Manager
• Issue DDL statements through intuitive API: createTable(), dropTable(), createForeignKey(), etc.
• Introspect your database schema as well: listTables(), listTableColumns(), listUsers(), etc.
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
$columns = array( 'id' => array( 'type' => Type::getType('integer'), 'autoincrement' => true, 'primary' => true, 'notnull' => true ), 'name' => array( 'type' => Type::getType('string'), 'length' => 255 ),);
$sm->dropAndCreateTable('user', $columns);
Drop and Create a Table
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Create a Foreign Key
$definition = array( 'name' => 'user_id_fk', 'local' => 'user_id', 'foreign' => 'id', 'foreignTable' => 'user');$sm->createForeignKey('profile', $definition);
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
So much more...• Fully featured DBAL for manipulating your
database with DDL statements
• Introspect your database and learn about it
• Execute queries and retrieve data
• Support for transactions
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
The ORM Key Feature
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Doctrine Query Language
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
DQL stands for Doctrine Query Language and is heavily
influenced by HQL from Hibernate
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Proprietary OQL(object query language) dialect
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
The DQL is parsed by a hand written recursive
descent parser
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Constructs AST
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
AST = Abstract Syntax Tree
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Tree representation of the syntactic structure of a source
language
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
PHP class names of DQL parser directly represent the language itself
OrderByClause.phpSelectClause.phpSelectExpression.phpSubselect.phpDeleteClause.phpetc. etc.
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Every DQL feature has a class to handle the parsing
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
• Easy to use
• Easy to expand and add new features
• Easy to use and understand the parsing of a DQL string
• Expand the DQL parser with your own functionality and add to the DQL language
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
DQL parser is very fast as it is. With final SQL caching it
becomes invisible.
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
$query = $em->createQuery( 'SELECT u, g, FROM User u ' . 'LEFT JOIN u.Groups g ' . 'ORDER BY u.name ASC, g.name ASC');$users = $query->execute();
Sample DQL Query
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Using the QueryBuilder
$qb = $em->createQueryBuilder() ->select('u, g') ->from('User', 'u') ->leftJoin('u.Groups', 'g') ->orderBy('u.name', 'ASC') ->addOrderBy('g.name', 'ASC');
$query = $qb->getQuery();
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Executing Queries
$users = $query->execute();
foreach ($users as $user) { // ... foreach ($user->getGroups() as $group) { // ... }}
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Working with Entities
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
The EntityManager
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
The EntityManager is responsible for managing the persistence of entities
$config = new \Doctrine\ORM\Configuration();$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);$config->setProxyDir(__DIR__ . '/Proxies');$config->setProxyNamespace('Proxies');
$connectionOptions = array( 'driver' => 'pdo_sqlite', 'path' => 'database.sqlite');
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Creating the EntityManager
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
$user = new User;$user->setUsername('jwage');$user->setPassword('changeme');
$profile = new Profile;$profile->setName('Jonathan H. Wage');
$user->setProfile($user);
$em->persist($user);$em->persist($profile);
$em->flush();
Persisting Entities
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Deleting Entities
$user1 = $em->find('User', 1);$user2 = $em->find('User', 2);
$em->remove($user1);$em->remove($user2);$em->flush();
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
EntityManager::flush()• Commits any changes to the managed
entities
• Efficiently executes insert, update and delete statements
• Keep number of flush() operations down to about 1-2 times per request
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
The EntityManager::flush() operation is able to insert,
update and delete entities very efficiently. It is ideal to keep
your flush operations to about 1-2 times per request
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Metadata Cache
$config = new \Doctrine\ORM\Configuration();$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ApcCache);
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
In production cache the ClassMetadata instances populated by the parsed
annotations, yaml, xml, etc.
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Query Cache
$config->setQueryCacheImpl(new \Doctrine\Common\Cache\ApcCache);
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
In production cache the parsing of a DQL query and the final SQL
generated.
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Result Cache
$config->setResultCacheImpl(new \Doctrine\Common\Cache\ApcCache);
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
In production cache the hydrated data of your queries to avoid unnecessary queries to the
database.
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
$query = $em->createQuery('SELECT u FROM Models\User u')$query->useResultCache(true, 3600, 'user_query');$users = $query->execute();
Using Result Cache
Execute it again and it pulls the results from the cache instead of hitting the database
$users = $query->execute();
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
$query = $em->createQuery('SELECT u FROM Models\User u')$query->useResultCache(true, 3600, 'user_query');$users = $query->execute();
Using Result Cache
Execute it again and it pulls the results from the cache instead of hitting the database
$users = $query->execute();
The parsing of this query will only ever happen once with the query cache
configured.
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Inheritance Mapping
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Mapped Superclasses
/** @MappedSuperclass */abstract class MappedSuperclassBase{ /** @Column(type="integer") */ private $mapped1;
/** @Column(type="string") */ private $mapped2;
/** * @OneToOne(targetEntity="MappedSuperclassRelated1") * @JoinColumn(name="related1_id", referencedColumnName="id") */ private $mappedRelated1;
// ... more fields and methods}
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Extend the Superclass
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
/** @Entity */class EntitySubClass extends MappedSuperclassBase{ /** @Id @Column(type="integer") */ private $id; /** @Column(type="string") */ private $name;
// ... more fields and methods}
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Single Table Inheritance
/** * @Entity * @InheritanceType("SINGLE_TABLE") * @DiscriminatorColumn(name="discriminator", type="string") * @DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) */class Person{ // ...}
/** * @Entity */class Employee extends Person{ // ...}
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Single Table• All classes of a hierarchy are mapped to a
single table
• Discriminator column used to distinguish type of a row in the database
• Efficient for querying across all types in the hierarchy or for specific types.
• Queries limited by type discriminator
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Class Table Inheritance
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
/** * @Entity * @InheritanceType("JOINED") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) */class Person{ // ...}
/** @Entity */class Employee extends Person{ // ...}
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Class Table• Each class in a hierarchy is mapped to
several tables
• Table of a child class is linked to the table of a parent class
• Discriminator column used to distinguish type of a row in the database
• Queries almost always require joins
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Testing
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
PHPUnit for Unit Testing
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
bambino:tests jwage$ phpunit Doctrine/Tests/AllTests.phpPHPUnit 3.3.17 by Sebastian Bergmann.
...............................................S.SS......... 60 / 673
............................................................ 120 / 673
............................................................ 180 / 673
...SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS.................... 240 / 673
............................................................ 300 / 673
............................................................ 360 / 673
............................................................ 420 / 673
............................................................ 480 / 673
............................................................ 540 / 673
............................................................ 600 / 673
.................SSSS.....................SS.S......S..SS.S. 660 / 673
.....S..SS.S.
Time: 3 seconds
OK, but incomplete or skipped tests!Tests: 673, Assertions: 1771, Skipped: 55.
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Sismo for Continuous Integration
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Growl Notifications
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Sismo keeps a close eye on all of our projects. We even run the Doctrine 2 tests
against multiple supported databases.
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Custom Types
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
namespace \Doctrine\DBAL\Types;
class MyCustomObjectType extends Type{ public function getName() { return 'MyCustomObjectType'; }
public function getSqlDeclaration(array $fieldDeclaration, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) { return $platform->getClobDeclarationSql($fieldDeclaration); }
public function convertToDatabaseValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) { return serialize($value); }
public function convertToPHPValue($value) { return unserialize($value); }}
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Type::addCustomType( 'MyCustomObjectType', 'Doctrine\DBAL\Types\MyCustomObjectType');
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Override Types
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
class MyString extends StringType{ }
Type::overrideType('string', 'Doctrine\DBAL\Types\MyString');
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
Thanks!!
Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com
Big Lamp Camp 2009 #eLAMP
You can contact Jonathan about Doctrine and Open-Source or for training, consulting, application development, or business
related questions at [email protected]
Jonathan H. [email protected]+1 415 992 5468
sensiolabs.com | doctrine-project.org | sympalphp.org | jwage.com