Doctrine 2: Enterprise Persistence Layer for PHP

Preview:

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.

Citation preview

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 jonathan.wage@sensio.com

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 <guilhermeblanco@hotmail.com> * @author Jonathan Wage <jonwage@gmail.com> * @author Roman Borschel <roman@code-factory.org> */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 jonathan.wage@sensio.com

Jonathan H. Wagejonathan.wage@sensio.com+1 415 992 5468

sensiolabs.com | doctrine-project.org | sympalphp.org | jwage.com

Recommended