doctrine 2: enterprise persistence layer for php

103
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

Upload: jonathan-wage

Post on 12-Jan-2015

19.213 views

Category:

Technology


0 download

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

Page 1: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 2: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 3: Doctrine 2: Enterprise Persistence Layer for PHP

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]

Page 4: Doctrine 2: Enterprise Persistence Layer for PHP

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?

Page 5: Doctrine 2: Enterprise Persistence Layer for PHP

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.

Page 6: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 7: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 8: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Doctrine 2.0

Page 9: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 10: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Three Main Packages

Page 11: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Common

Page 12: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

DBAL

Page 13: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

ORM

Page 14: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Fully implements namespaces

Page 15: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 16: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 17: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 18: Doctrine 2: Enterprise Persistence Layer for PHP

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 :)

Page 19: Doctrine 2: Enterprise Persistence Layer for 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

Page 20: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 21: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 22: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

20% Faster

Page 23: Doctrine 2: Enterprise Persistence Layer for PHP

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!

Page 24: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 25: Doctrine 2: Enterprise Persistence Layer for PHP

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!

Page 26: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 27: Doctrine 2: Enterprise Persistence Layer for PHP

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!!

Page 28: Doctrine 2: Enterprise Persistence Layer for PHP

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); }}

Page 29: Doctrine 2: Enterprise Persistence Layer for PHP

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 :)

Page 30: Doctrine 2: Enterprise Persistence Layer for PHP

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.

Page 31: Doctrine 2: Enterprise Persistence Layer for PHP

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;}

Page 32: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 33: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 34: Doctrine 2: Enterprise Persistence Layer for PHP

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);

Page 35: Doctrine 2: Enterprise Persistence Layer for PHP

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);

Page 36: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 37: Doctrine 2: Enterprise Persistence Layer for PHP

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!

Page 38: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 39: Doctrine 2: Enterprise Persistence Layer for PHP

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.

Page 40: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

DBAL Examples

Page 41: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 42: Doctrine 2: Enterprise Persistence Layer for PHP

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();

Page 43: Doctrine 2: Enterprise Persistence Layer for PHP

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.

Page 44: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 45: Doctrine 2: Enterprise Persistence Layer for PHP

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);

Page 46: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 47: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 48: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Doctrine Query Language

Page 49: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 50: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 51: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 52: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Constructs AST

Page 53: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 54: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 55: Doctrine 2: Enterprise Persistence Layer for PHP

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.

Page 56: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 57: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 58: Doctrine 2: Enterprise Persistence Layer for PHP

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.

Page 59: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 60: Doctrine 2: Enterprise Persistence Layer for PHP

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();

Page 61: Doctrine 2: Enterprise Persistence Layer for PHP

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) { // ... }}

Page 62: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Working with Entities

Page 63: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

The EntityManager

Page 64: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 65: Doctrine 2: Enterprise Persistence Layer for PHP

$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

Page 66: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 67: Doctrine 2: Enterprise Persistence Layer for PHP

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();

Page 68: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 69: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 70: Doctrine 2: Enterprise Persistence Layer for PHP

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);

Page 71: Doctrine 2: Enterprise Persistence Layer for PHP

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.

Page 72: Doctrine 2: Enterprise Persistence Layer for PHP

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);

Page 73: Doctrine 2: Enterprise Persistence Layer for PHP

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.

Page 74: Doctrine 2: Enterprise Persistence Layer for PHP

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);

Page 75: Doctrine 2: Enterprise Persistence Layer for PHP

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.

Page 76: Doctrine 2: Enterprise Persistence Layer for PHP

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();

Page 77: Doctrine 2: Enterprise Persistence Layer for PHP

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.

Page 78: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Inheritance Mapping

Page 79: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Mapped Superclasses

Page 80: Doctrine 2: Enterprise Persistence Layer for PHP

/** @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

Page 81: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Extend the Superclass

Page 82: Doctrine 2: Enterprise Persistence Layer for PHP

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}

Page 83: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Single Table Inheritance

Page 84: Doctrine 2: Enterprise Persistence Layer for PHP

/** * @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

Page 85: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 86: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Class Table Inheritance

Page 87: Doctrine 2: Enterprise Persistence Layer for PHP

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{ // ...}

Page 88: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 89: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Testing

Page 90: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 91: Doctrine 2: Enterprise Persistence Layer for PHP

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.

Page 92: Doctrine 2: Enterprise Persistence Layer for PHP

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

Page 93: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Page 94: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Page 95: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Growl Notifications

Page 96: Doctrine 2: Enterprise Persistence Layer for PHP

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.

Page 97: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Custom Types

Page 98: Doctrine 2: Enterprise Persistence Layer for PHP

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); }}

Page 99: Doctrine 2: Enterprise Persistence Layer for PHP

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');

Page 100: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Override Types

Page 101: Doctrine 2: Enterprise Persistence Layer for PHP

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');

Page 102: Doctrine 2: Enterprise Persistence Layer for PHP

Doctrine 2: Enterprise Persistence Layer for PHP 5.3 www.doctrine-project.org www.sensiolabs.com

Big Lamp Camp 2009 #eLAMP

Thanks!!

Page 103: Doctrine 2: Enterprise Persistence Layer for PHP

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