Doctrine 2 ORM
ORM?
Object Relational
    Mapping
Objektgraph   Tabellen &
              Relationen
Doctrine 2?
Doctrine 2

Code-Bibliothek für PHP >= 5.3.2

Inspiriert von JPA & Hibernate

Von den Machern von Symfony

De-Facto Standard für ORM in PHP

Für MySQL & Co., aber ...
Doctrine 2

... funktioniert auch mit CouchDB, MongoDB
& Co.

ORM trifft es daher eigentlich gar nicht
(mehr)

Ziel: „Mach dir keine Sorgen mehr um die
Persistenz deiner Objekte.“
Doctrine „Projects“
 Ab hier
                ORM
wird‘s cool.


                DBAL



               Common
Common



Class Loading

Annotations
DBAL
Wrapper um PDO

Verbindungsmanagement

SQL-Query Builder

Events (z.B. PostConnect)

Schema Manager

…
ORM



Persistenz für PHP Objekte

Objekt-Orientierte Abfragesprache (DQL)
Installation

Via archive download, git clone oder PEAR

Setup Autoloader

Entity Manager mit Konfigurationsobjekt
initialisieren (DB-Infos, Caching, Pfade, etc.)

(alle Details im Manual)
Exkurs: ZF-Boilerplate
Zend Framework
Development
Plattform

ZF + Doctrine 2 +
PHPUnit + Vagrant +
ElasticSearch + ...

Virtual Box

Open Source
Exkurs: ZF-Boilerplate
Installation Ruby + Vagrant + Virtual Box lokal

git clone https://michael-romer@github.com/michael-
romer/zf-boilerplate.git myApp

$ vagrant box add lucid32 http://files.vagrantup.com/
lucid32.box

$ vagrant up

http://localhost:8080 im Browser aufrufen
ORM Akteure

         EntityManager



Entity               Repository
Entity
POPO (= Plain Old PHP Object)

Keine Persistenz-Basisklasse (mehr)
notwendig

Meta-Informationen zur Persistenz als
Annotationen (XML, YAML ebenfalls möglich)

  Tabellen-Ebene

  Feld-Ebene

  Assoziationen
Klasse „App“
Entity „App“
Entity Manager
Konfigurierte Klasse zum Lifecycle-
Management der Entities.

  Verbindungdaten

  Caching-Konfiguration

  MetaData-Driver (z.B. Annotations oder
  YAML)

  …
Entity Manager
Entity Manager
       Internals
Unit-of-Work Pattern

Verfolgt Änderungen via
Identity Map mit Objektkopien

Dank PHP‘s „Copy-On-Write“
resourcenschonend

Wiederholtes Laden einer
Entity aus Map
Repository


Laden von Entities via Repositories

Default-Repository für Entities

  findAll, findOne, findBy, findOneBy, ...

Custom-Repositories halten alle DB-Queries
Repository
Entity „App“ mit Custom
         Repo
DQL (Doctrine Query
     Language)
Abfragesprache, angelehnt an SQL, aber
„objektorientiert“ formuliert

Vereinfacht Umgang mit Objekteigenschaften
und Assoziationen
Assoziationen
Analog zu Objekteigenschaften durch
Annotationen kenntlich gemacht

1-1, 1-n und n-n, self-referencing, uni- und
bidirektionale Assoziationen

Support für Composite Keys
Assoziationen
Assoziationen
Assoziationen
Entity Proxies
Wird eine App aus der DB geladen, wird
standardmäßig nicht die Users collection
mitgeladen.

Doctrine generiert Proxy-Klassen, die
stellvertretend verwendet werden (instanceof
User == true), bis die Entity tatsächlich
verwendet wird.

Wird eine Assoziation (e.g. foreach)
traversiert, erkennt dies Doctrine und lädt
alle Entities.
Vererbung
Unterstützung für

   Mapped Superclass

       „Daten-Mixin“

   Single Table Inheritence

       Alle Klassen der Hierarchie in einer Tabelle abgebildet

       Descriminator Column zur Klassenbestimmung

       Keine Joins notwendig

Class Table Inheritence

   Jede Klasse hat eigene Tabelle mit individuellen Eigenschaften
Events
Eventsystem für „Custom-Events“

Entity-Lifecycle-Events

preRemove, postRemove, prePersist ,
postPersist, preUpdate, postUpdate, postLoad,
loadClassMetadata, onFlush, onClear
SQL

Native SQL Abfragen bei Bedarf möglich

Custom Mapping von Spalten auf
Eigenschaften

Ggf. Partial Objects zwecks Performance-
Optimierung
Caching
Drivers

  Array

  APC

  Memcached

  XCache

Arten

  DQL Query Cache (SQL Statements)

  Result Cache (Entites)

  Metadata Cache (Annotationen, YAML, etc.)
DQL, Teil 2
Unterstützung für

  Aggregationen (z.B. COUNT)

  Funktionen (z.B. CONCAT)

  Operatoren (z.B. Arithmetik)
Transaktionen
Implizit durch „Unit-of-Work“

Explizit durch
Locking
Support für „User-Think-Time“ Locking

Optimistisch

  „Es wird schon gutgehen!“

  Versions-Feld (int oder timestamp)

  Wirft ggf. Exception

Pessimistisch

  „Lieber nichts riskieren!“

  Nur auf DB-Ebene
Doctrine Console (CLI)
Installation via PEAR (oder manuell)

Standard-Kommandos + Eigene Kommandos
(analog Zend_Tool)

Doctrine Console

  $ doctrine orm:generate-entities --help

  z.B. $ dbal:import / Import SQL file(s) in DB
                      /

  z.B. $ php doctrine.php orm:schema-
  tool:create / Erzeugung DB Schema
               /
Extensions
Doctrine Extensions (Behavior)

   Versionable

   Sortable

   Loggable

   Translateable

   Tree / Nested Set

   …

https://github.com/l3pp4rd/DoctrineExtensions

https://github.com/beberlei/DoctrineExtensions
Fin


Doctrine 2: http://www.doctrine-project.org/

Enterprise Patterns: http://martinfowler.com/

ZF-Boilerplate: http://zf-boilerplate.com

Mein Blog: http://www.startup-patterns.de/

Doctrine 2 - An Introduction (German)