SlideShare ist ein Scribd-Unternehmen logo
1 von 79
Downloaden Sie, um offline zu lesen
Guilherme Blanco, Yahoo!


           Doctrine 2
           Enterprise Persistence Layer for PHP




quarta-feira, 2 de junho de 2010
Who am I?
         10+ years web developer

         Open Source evangelist

         Works for Yahoo!

         Contributes to...
            ...Doctrine
            ...Zend Framework
            ...Symfony
            ...PHP
            etc

         Likes to sing and also fish on spare time! =)

quarta-feira, 2 de junho de 2010
Who am I?
         http://www.twitter.com/guilhermeblanco

         http://www.facebook.com/guilhermeblanco




quarta-feira, 2 de junho de 2010
Doctrine 2



quarta-feira, 2 de junho de 2010
Doctrine 2
         PHP 5.3+

         100% code rewritten

         Fully namespaced code




quarta-feira, 2 de junho de 2010
Doctrine 2
         Tools used:
             phpUnit  Unit testing
             Phing Packaging and distribution
             Symfony Components
                YAML
                Console
             Sismo Continuous Integration
             GIT Source version control
             JIRA Issue tracking and management
             Trac Timeline, source code & changeset viewer




quarta-feira, 2 de junho de 2010
Doctrine 2
         Three main packages:
             Common


             DBAL


             ORM




quarta-feira, 2 de junho de 2010
DoctrineCommon
     git@github.com:doctrine/common.git

         Cache Drivers




quarta-feira, 2 de junho de 2010
DoctrineCommonCache
         Supported Drivers:
             APCCache
     $cacheDriver = new DoctrineCommonCacheApcCache();

             MemcacheCache
     $memcache = new Memcache();
     $memcache->addServer('memcache_host', 11211);

     $cacheDriver = new DoctrineCommonCacheMemcacheCache();
     $cacheDriver->setMemcache($memcache);

             XcacheCache
     $cacheDriver = new DoctrineCommonCacheXcacheCache();




quarta-feira, 2 de junho de 2010
DoctrineCommonCache
         Cache Drivers Interface:
     interface DoctrineCommonCacheCache {
       function setNamespace($namespace);
       function getIds();

          function fetch($id);

          function contains($id);

          function save($id, $data, $lifeTime = 0);

          function delete($id);
          function deleteAll();

          function deleteByRegex($regex);
          function deleteByPrefix($prefix);
          function deleteBySuffix($suffix);
     }
quarta-feira, 2 de junho de 2010
DoctrineCommon
     git@github.com:doctrine/common.git

         Cache Drivers

         Class Loader




quarta-feira, 2 de junho de 2010
DoctrineCommonClassLoader
         Implements PSR #0
             PSR        = PHP Standards Recommendation

             Technical             Interoperability between libraries
                     Symfony, Zend Framework, Doctrine, Agavi, PEAR2/Pyrus,
                      Lithium, Flow3, Solar, etc

             Possible             merge in PHP core: SplClassLoader
                     http://wiki.php.net/rfc/splclassloader




quarta-feira, 2 de junho de 2010
DoctrineCommonClassLoader
        Usage:

     require_once '/path/to/lib/Doctrine/Common/ClassLoader.php';

     $doctrineClassLoader = new DoctrineCommonClassLoader(
         'Doctrine', '/path/to/lib/Doctrine'
     );

     $doctrineClassLoader->register();




quarta-feira, 2 de junho de 2010
DoctrineCommon
     git@github.com:doctrine/common.git

         Cache Drivers

         Class Loader

         Collections




quarta-feira, 2 de junho de 2010
DoctrineCommonCollections
         Solution inspired in java.util.Collection interface

         Plain PHP arrays are hard to manipulate

         ..but custom array implementations are not
          compatible with array_* functions

         Heavily usage of Closures

         User-land SplArray
             Where           are the PHP devs?
quarta-feira, 2 de junho de 2010
DoctrineCommon
     git@github.com:doctrine/common.git

         Cache Drivers

         Class Loader

         Collections

         Lexer

         Annotations Parser

quarta-feira, 2 de junho de 2010
DoctrineCommonAnnotations
         Java like Annotations

         Define metadata information in classes

         Reusable and highly extendable

         Suppress missing PHP functionality
             Again, where are the PHP devs?
             RFC already written: http://wiki.php.net/rfc/annotations




quarta-feira, 2 de junho de 2010
DoctrineCommonAnnotations
     Annotations                   ::=   Annotation {[ "*" ]* [Annotation]}*
     Annotation                    ::=   "@" AnnotationName ["(" [Values] ")"]
     AnnotationName                ::=   QualifiedName | SimpleName | AliasedName
     QualifiedName                 ::=   NameSpacePart "" {NameSpacePart ""}*
                                         SimpleName
     AliasedName                   ::=   Alias ":" SimpleName
     NameSpacePart                 ::=   identifier
     SimpleName                    ::=   identifier
     Alias                         ::=   identifier
     Values                        ::=   Array | Value {"," Value}*
     Value                         ::=   PlainValue | FieldAssignment
     PlainValue                    ::=   integer | string | float | boolean |
                                         Array | Annotation
     FieldAssignment               ::=   FieldName "=" PlainValue
     FieldName                     ::=   identifier
     Array                         ::=   "{" ArrayEntry {"," ArrayEntry}* "}"
     ArrayEntry                    ::=   Value | KeyValuePair
     KeyValuePair                  ::=   Key "=" PlainValue
     Key                           ::=   string | integer


quarta-feira, 2 de junho de 2010
DoctrineCommonAnnotations
         Creating Annotations classes:
     final class DoctrineORMMappingEntity
         extends DoctrineCommonAnnotationsAnnotation {
         public $repositoryClass;
     }

         Using Annotations:
     namespace MyProjectEntity;

     /**
       * @Entity(repositoryClass="RepositoryUserRepository")
       */
     class User {
          // ...
     }

quarta-feira, 2 de junho de 2010
DoctrineCommonAnnotations
         Reading Annotations:
     $reader = new DoctrineCommonAnnotationsAnnotationReader(
         new DoctrineCommonCacheArrayCache()
     );
     $reader->setDefaultAnnotationNamespace(
         'DoctrineORMMapping'
     );

     $class = new ReflectionClass('MyProjectEntityUser');
     $classAnnotations = $reader->getClassAnnotations($class);

     echo $classAnnotations['DoctrineORMMappingEntity']
              ->repositoryClass;




quarta-feira, 2 de junho de 2010
DoctrineCommonAnnotations
     interface DoctrineCommonAnnotationsAnnotationReader {
       function setDefaultAnnotationNamespace($defaultNamespace);

         function setAnnotationNamespaceAlias($namespace, $alias);

         function getClassAnnotations(ReflectionClass $class);

         function getClassAnnotation(ReflectionClass $class, $annot);

         function getPropertyAnnotations(ReflectionProperty $property);

         function getPropertyAnnotation(
             ReflectionProperty $property, $annot
         );

         function getMethodAnnotations(ReflectionMethod $method);

         function getMethodAnnotation(ReflectionMethod $method, $annot);
     }



quarta-feira, 2 de junho de 2010
DoctrineDBAL
     git@github.com:doctrine/dbal.git

         Database Abstraction Layer built at the top of PDO and
          proprietary drivers

         Supported drivers:
            DB2
            Microsoft SQL Server (pdo_sqlsrv & sqlsrv)
            MySQL
            PostgreSQL
            Oracle
            SQLite


quarta-feira, 2 de junho de 2010
DoctrineDBAL
         Improved API for Database introspection and
          schema management

         Hopefully it can be a defacto standard DBAL for
          PHP 5.3 in the future, like MDB2 for PEAR1

         Inspired in ezcDatabase, MDB2 and Zend_Db

         Maybe we can make this happen for PEAR2



quarta-feira, 2 de junho de 2010
DoctrineDBAL
     interface DoctrineDBALConnection {
       // Data manipulation API

         /* Executes an SQL DELETE statement on a table. */
         function delete($tableName, array $identifier);

         /* Executes an SQL UPDATE statement on a table. */
         function update($tableName, array $data, array $identifier);

         /* Inserts a table row with specified data. */
         function insert($tableName, array $data);

         /* Prepares an SQL statement. Returns a DBALStatement */
         function prepare($statement);

         /* Applies a SQL statement and return # of affected rows. */
         function exec($statement);

         // ...

quarta-feira, 2 de junho de 2010
DoctrineDBAL
         // Transaction API

         /* Returns the current transaction nesting level. */
         function getTransactionNestingLevel();

         /* Executes a function in a transaction. */
         function transactional(Closure $func);

         /* Starts a transaction by suspending auto-commit mode. */
         function beginTransaction();

         /* Commits the current transaction. */
         function commit();

         /* Cancel any database changes done during current transaction. */
         function rollback();

         /* Check if current transaction is marked for rollback only. */
         function isRollbackOnly();

         // ...
quarta-feira, 2 de junho de 2010
DoctrineDBAL
         // Data fetching API

         /* Executes a SQL query and returns first row as an assoc array. */
         function fetchAssoc($statement, array $params = array());

         /* Executes a SQL query and returns first row as a numeric array. */
         function fetchArray($statement, array $params = array());

         /* Executes a SQL query and returns first column value of result. */
         function fetchColumn(
            $statement, array $params = array(), $colnum = 0
         );

         /* Executes a SQL query and returns the result as an assoc array. */
         function fetchAll($sql, array $params = array());
     }




quarta-feira, 2 de junho de 2010
DoctrineDBALTypes
         Centralized point to convert values
             From Database to PHP
             From PHP to Database


         Database agnostic

         Accessing specific DB dialect called Platform

         Extendable



quarta-feira, 2 de junho de 2010
DoctrineDBALTypes
         New DataType is just implement an abstract class:
    interface DoctrineDBALTypesType {
        function convertToDatabaseValue(
            $value, AbstractPlatform $platform
        );

            function convertToPHPValue(
                $value, AbstractPlatform $platform
            );

            function getSqlDeclaration(
                array $fieldDeclaration, AbstractPlatform $platform
            );

            function getName();

            function getBindingType();
    }

quarta-feira, 2 de junho de 2010
DoctrineDBAL
     class MyProjectDataTypesMyObjectType extends DoctrineDBALTypesType
     {
       public function getSqlDeclaration(
         array $fieldDeclaration, AbstractPlatform $platform
       ) {
         return $platform->getClobTypeDeclarationSQL($fieldDeclaration);
       }

         public function convertToDatabaseValue(
           $value, AbstractPlatform $platform
         ) {
           return serialize($value);
         }

         public function convertToPHPValue($value, AbstractPlatform $platform) {
           $value = (is_resource($value)) ? stream_get_contents($value) : $value;
           return unserialize($value);
         }

         public function getName() {
           return "my-object";
         }
     }

quarta-feira, 2 de junho de 2010
DoctrineDBALTypes
         Finally, make Doctrine know about your DataType:
    DoctrineDBALTypesType::addType(
        "my-object", "MyProjectDataTypesMyObjectType"
    );

         Then you can use it in your Entities!
    /**
     * @Entity
     * @Table(name="files")
     */
    class File {
        // ...

            /**
             * @Column(type="my-object")
             */
            protected $content;
    }
quarta-feira, 2 de junho de 2010
DoctrineDBAL
         Creating a schema:
    $platform = $em->getConnection()->getDatabasePlatform();

    $schema = new DoctrineDBALSchemaSchema();
    $table = $schema->createTable("users");
    $table->addColumn("id", "integer", array("unsigned" => true));
    $table->addColumn("name", "string", array("length" => 32));
    $table->setPrimaryKey(array("id"));

    // get queries to create this schema.
    $queries = $schema->toSql($platform);

    Array(
      0 => 'CREATE TABLE users (
               id INTEGER NOT NULL,
               name VARCHAR(32) NOT NULL,
               PRIMARY KEY("id")
           )'
    )

quarta-feira, 2 de junho de 2010
DoctrineDBAL
         Deleting a schema:
    // get queries to safely delete the schema.
    $queries = $schema->toDropSql($platform);


    Array(
      0 => 'DROP TABLE users'
    )


         It does the reverse of what ->toSql() does




quarta-feira, 2 de junho de 2010
DoctrineDBAL
         Comparing schemas:
    $platform = $em->getConnection()->getDatabasePlatform();

    $fromSchema = new DoctrineDBALSchemaSchema();
    $table = $fromSchema->createTable("users");
    $table->addColumn("id", "integer", array("unsigned" => true));
    $table->addColumn("name", "string", array("length" => 32));
    $table->setPrimaryKey(array("id"));




quarta-feira, 2 de junho de 2010
DoctrineDBAL
        Comparing schemas:
    $platform = $em->getConnection()->getDatabasePlatform();

    $toSchema = new DoctrineDBALSchemaSchema();
    $table = $toSchema->createTable("users");
    $table->addColumn("id", "integer", array("unsigned" => true));
    $table->addColumn("name", "string", array("length" => 32));
    $table->addColumn("email", "string", array("length" => 255));
    $table->setPrimaryKey(array("id"));




quarta-feira, 2 de junho de 2010
DoctrineDBAL
         Comparing schemas:
    $platform = $em->getConnection()->getDatabasePlatform();

    $comparator = new DoctrineDBALSchemaComparator();
    $schemaDiff = $comparator->compare($fromSchema, $toSchema);

    // queries to get from one to another schema.
    $queries = $schemaDiff->toSql($platform);


    Array(
      0 => 'ALTER TABLE users ADD email VARCHAR(255) NOT NULL'
    )




quarta-feira, 2 de junho de 2010
Insert Performance
         Inserting 20 entries with Doctrine 2:
    for ($i = 0; $i < 20; $i++) {
        $user = new User();
        $user->name = 'Guilherme Blanco';
        $em->persist($user);
    }

    $start = microtime(0);
    $em->flush();
    $end = microtime(0);

    echo $end - $start;




quarta-feira, 2 de junho de 2010
Insert Performance
         Inserting 20 entries with raw PHP code:
    $start = microtime(0);

    for ($i = 0; $i < 20; $i++) {
        mysql_query(
            "INSERT INTO users (name) VALUES ('Guilherme Blanco')",
            $db_link
        );
    }

    $end = microtime(0);

    echo $end - $start;




quarta-feira, 2 de junho de 2010
Insert Performance
         We are not kidding here! =P
          Which one do you think it is faster?
             Doctrine             2
                     Took: 0.0094 seconds
             PHP        code
                     Took: 0.0165 seconds

         WTH?!?! Doctrine 2 is faster than raw PHP?
             Itdoes a lot less, provides no features, no abstraction!
             Answer is TRANSACTIONS!
              Doctrine 2 manages our transactions and efficiently
              executes all inserts in a single.


quarta-feira, 2 de junho de 2010
Insert Performance
         Doctrine 2 *IS NOT* faster than raw PHP code

         Simple developers oversights can cause
          significant performance problems!




quarta-feira, 2 de junho de 2010
Insert Performance
         Inserting 20 entries with raw PHP code (revisited):
    $start = microtime(0);

    mysql_query("START TRANSACTION", $db_link);

    for ($i = 0; $i < 20; $i++) {
        mysql_query(
            "INSERT INTO users (name) VALUES ('Guilherme Blanco')",
            $db_link
        );
    }

    mysql_query("COMMIT", $db_link);

    $end = microtime(0);

    echo $end - $start;


quarta-feira, 2 de junho de 2010
Insert Performance
         Final performance information...
             Doctrine             2
                     Took: 0.0094 seconds
             PHP        code
                     Took: 0.0165 seconds
             PHP        code (revisited)
                     Took: 0.0028 seconds


         You can read more about this on Doctrine Blog
               http://www.doctrine-project.org/blog/transactions-and-performance




quarta-feira, 2 de junho de 2010
DoctrineORM
         What have we learned from Doctrine 1?
             Persistence Layer != Domain Model
             Focus on our key purpose, the Persistence Layer
             “You’re doing it wrong!”
             Kill magic




quarta-feira, 2 de junho de 2010
DoctrineORM
         Performance comparison
             Hydrating            5000 records
                   Doctrine 1.2: 4.3 seconds
                   Doctrine 2.0-DEV: 1.4 seconds

             Hydrating            10000 records
                     Doctrine 2.0-DEV: 3.5 seconds

         Twice records and still faster than Doctrine 1!




quarta-feira, 2 de junho de 2010
DoctrineORM
         Why is it faster?
             PHP        5.3 optimizations!
                   30% less resources usage, 20% faster
                   5.3-DEV (lazy bucket alloc, interned strings, runtime cache),
                    Doctrine 2 can run 50% faster!
             Better Hydration algorithm
             Topological Sorting
             Slim Entities
             Killed magic aspects of Doctrine 1




quarta-feira, 2 de junho de 2010
DoctrineORM
         Why kill magic?
             Eliminate            the WTF/minute (WTF factor)

             Hard to debug
             Edge cases are hard to fix
             Edge cases are hard to workaround


             Everything            works until you go outside the box

             ...and        magic is slow! I can prove it!
                   __set is ~87% slower than normal set
                   __get is ~150% slower than normal get



quarta-feira, 2 de junho de 2010
DoctrineORM
         How we kill magic?
             We       call it OOP!

             Object Composition
             Inheritance
             Aggregation
             Containment
             Encapsulation
             etc




quarta-feira, 2 de junho de 2010
DoctrineORM
         DataMapper instead of ActiveRecord

         Heavily inspired by JSR-317, a.k.a. JPA v2.0

         Java... WHAT?!?! #$@&*!
             PHP still lacks of standards
             PHP Standards Group can rescue us?!


         Final 2.0.0 version expected for September 1st



quarta-feira, 2 de junho de 2010
DoctrineORM
         Entities
             Regular  PHP class
             Lightweight persistent domain object
             Do not extend any base class!
             Cannot be final or contain final methods
             Two entities in a hierarchy of classes can not map
              property with the same name
             Abstract and concrete classes can be Entities
             Entities may extend non-entity classes as well as entity
              classes
             Non-entity classes may also extend entity classes



quarta-feira, 2 de junho de 2010
DoctrineORM
     namespace Entity;

     /**
      * @Entity
      * @Table(name="users")
      */
     class User {
         /**
          * @Id @GeneratedValue
          * @Column(type="integer")
          */
         protected $id;

             /**
              * @Column(type="string", length=32)
              */
             protected $name;

             // ... getters and setters
     }
quarta-feira, 2 de junho de 2010
DoctrineORM
    EntityUser:
      type: entity
      table: users
      id:
        id:
          type: integer
          generator:
            strategy: AUTO
      fields:
        name:
          type: string
          length: 32




quarta-feira, 2 de junho de 2010
DoctrineORM
    <?xml version="1.0" encoding="UTF-8"?>
    <doctrine-mapping
       xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
    http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
       <entity name="EntityUser" table="users">
          <id name="id" type="integer">
             <generator strategy="AUTO"/>
          </id>
          <field name="name" type="string" length="50"/>
       </entity>
    </doctrine-mapping>




quarta-feira, 2 de junho de 2010
DoctrineORM
        Column mapping
             type
             length
             scale, precision
             nullable
             unique
             name (DB)
             options
             columnDefinition

    /**
     * @Column(type="string", length=32, unique=true)
     */
    protected $foo;

quarta-feira, 2 de junho de 2010
DoctrineORM
        Identifier fields
             Supports             different strategies:
                   AUTO
                   SEQUENCE
                   TABLE
                   NONE

    /**
     * @Id @GeneratedValue(strategy="AUTO")
     * @Column(type="integer")
     */
    protected $id;




quarta-feira, 2 de junho de 2010
DoctrineORM
        Association fields
               OneToOne
    /** @OneToOne(targetEntity="Shipping") */
    private $shipping;

             OneToMany
             ManyToOne
             ManyToMany

    /**
     * @ManyToMany(targetEntity="Group")
     * @JoinTable(name="users_groups", joinColumns={
     *    @JoinColumn(name="user_id", referencedColumnName="id")
     * }, inverseJoinColumns={
     *    @JoinColumn(name="group_id", referencedColumnName="id")
     * })
     */
    private $groups;
quarta-feira, 2 de junho de 2010
DoctrineORM
         Inheritance
             Concrete             Table Inheritance
                   No irrelevant columns
                   No locking problems


                   Difficult to deal with Primary Keys
                   No relations in base class
                   Search on superclass means search in all tables (too much
                    queries or a weird join)
                   Refactoring of fields means update a few or all table




quarta-feira, 2 de junho de 2010
DoctrineORM
     /** @MappedSuperclass */
     class MappedSuperclassBase {
         /** @Column(type="string") */
         protected $mapped;

            /**
             * @OneToOne(targetEntity="MappedSuperclassRelated")
             * @JoinColumn(name="related_id", referencedColumnName="id")
             */
            protected $related;
     }

     /** @Entity @Table(name="users") */
     class User extends MappedSuperclassBase {
         /** @Id @Column(type="integer") */
         protected $id;

            /** @Column(type="string", length=32) */
            protected $name;
     }



quarta-feira, 2 de junho de 2010
DoctrineORM
     CREATE TABLE users (
         mapped TEXT NOT NULL,
         id INTEGER NOT NULL,
         name TEXT NOT NULL,
         related_id INTEGER DEFAULT NULL,
         PRIMARY KEY(id)
     );




quarta-feira, 2 de junho de 2010
DoctrineORM
         Inheritance
             Single         Table Inheritance
                   Only one table on database
                   No joins
                   Refactoring of fields do not change DB schema


                   Waste of space on database
                   Too many locks due to many accesses
                   No duplicated name of fields with different meaning




quarta-feira, 2 de junho de 2010
DoctrineORM
     namespace MyProjectEntity;

     /**
       * @Entity
       * @InheritanceType("SINGLE_TABLE")
       * @DiscriminatorColumn(name="discr", type="string")
       * @DiscriminatorMap({
       *     "user" = "User", "employee" = "Employee"
       * })
       */
     class User {
          // ...
     }

     /** @Entity */
     class Employee extends User {
         // ...
     }




quarta-feira, 2 de junho de 2010
DoctrineORM
         Inheritance
             Class        Table Inheritance
                   Easy to understand
                   DB space is optimized due to normalization
                   Direct relationship between Domain Model and database


                   Too many joins
                   Refactoring of fields need a database schema update
                   Supertype table accessed a lot, may be in lock mode




quarta-feira, 2 de junho de 2010
DoctrineORM
     namespace MyProjectEntity;

     /**
       * @Entity
       * @InheritanceType("JOINED")
       * @DiscriminatorColumn(name="discr", type="string")
       * @DiscriminatorMap({
       *     "user" = "User", "employee" = "Employee"
       * })
       */
     class User {
          // ...
     }

     /** @Entity */
     class Employee extends User {
         // ...
     }




quarta-feira, 2 de junho de 2010
DoctrineORM
         Proxies
             Lazy-load Entity data
             Provide the possibility to get an Entity reference
              without database access
             Can be generated on-the-fly (during script execution)
              or via a Console tool

    $proxyUser = $em->getReference("User", 1);




quarta-feira, 2 de junho de 2010
DoctrineORM
         EntityManager
             Central  point of ORM functionality
             Employes Transaction Write Behind strategy that
              delays executions of SQL statements
             ...this means, efficiency!
             ...and also means that write locks are quickly released!


             Internally,  it uses a UnitOfWork to keep track of your
                objects state




quarta-feira, 2 de junho de 2010
DoctrineORM
     interface DoctrineORMEntityManager {
         // Transaction API

            /* Starts a transaction on the underlying database connection. */
            function beginTransaction();

            /* Commits a transaction on underlying database connection. */
            function commit();

            /* Flushes all changes to queued objects to the database. */
            function flush();

            /* Performs a rollback on the underlying database connection. */
            function rollback();

            /* Executes a function in a transaction. */
            function transactional(Closure $func);

            // ...



quarta-feira, 2 de junho de 2010
DoctrineORM
            // Query API

            /* Creates a new Query object. */
            function createQuery($dql);

            /* Creates a native SQL query. */
            function createNativeQuery(
                $sql, DoctrineORMQueryResultSetMapping $rsm
            );

            /* Create a QueryBuilder instance. */
            function createQueryBuilder();

            /* Finds an Entity by its identifier. */
         function find($entityName, $identifier, $lockMode =
     LockMode::NONE, $lockVersion = null);

         /* Gets a reference to the entity identified by the given type and
     identifier without actually loading it. */
            function getReference($entityName, $identifier);

            // ...
quarta-feira, 2 de junho de 2010
DoctrineORM
            // Object Manipulation API

            /* Tells EntityManager to make instance managed and persistent. */
            function persist($entity);

            /* Removes an entity instance. */
            function remove($entity);

            /* Refresh state of entity from database, overrides changes. */
            function refresh($entity);

            /* Detaches an entity from the EntityManager. */
            function detach($entity);

            /* Merges state of detached entity into persistence context. */
            function merge($entity);

            // ...




quarta-feira, 2 de junho de 2010
DoctrineORM
            // Repository, Configuration, EventManager, etc

            /* Gets the EventManager used by the EntityManager. */
            function getEventManager();

            /* Gets the Configuration used by the EntityManager. */
            function getConfiguration();

            /* Gets the repository for an entity class. */
            function getRepository($entityName);

            /* Returns the metadata for a class. */
            function getClassMetadata($className);

            /* Gets database connection object used by the EntityManager. */
            function getConnection();
     }




quarta-feira, 2 de junho de 2010
DoctrineORM
        Working with Entities in EntityManager
               Creating an EntityManager
    $config = new DoctrineORMConfiguration();

    $config->setMetadataCacheImpl($cacheDriver);
    $config->setQueryCacheImpl($cacheDriver);

    $config->setProxyDir("/path/to/MyProject/Proxies");
    $config->setProxyNamespace("MyProjectProxies");

    $connectionOptions = array(
        "driver" => "pdo_sqlite",
        "path"   => "database.sqlite"
    );

    // Creating the EntityManager
    $em = DoctrineORMEntityManager::create(
        $connectionOptions, $config
    );
quarta-feira, 2 de junho de 2010
DoctrineORM
        Working with Entities in EntityManager
               Persisting Entities
    try {
        $em->transactional(function ($em) {
            $user = new MyProjectEntityUser();
            $user->name = "Guilherme Blanco";

                    $em->persist($user);
        });
    } catch (Exception $e) {
        // ...
    }




quarta-feira, 2 de junho de 2010
DoctrineORM
        Working with Entities in EntityManager
               Updating Entities
    try {
        $em->transactional(function ($em) {
            $user = $em->find("MyProjectEntityUser", 1);
            $user->name = "Benjamin Eberlei";

                    $em->persist($user);
        });
    } catch (Exception $e) {
        // ...
    }




quarta-feira, 2 de junho de 2010
DoctrineORM
        Working with Entities in EntityManager
               Deleting Entities
    try {
        $em->transactional(function ($em) {
            $user = $em->getReference("MyProjectEntityUser", 1);

                    $em->remove($user);
        });
    } catch (Exception $e) {
        // ...
    }




quarta-feira, 2 de junho de 2010
DoctrineORM
         Doctrine Query Language (DQL)
             Implementation   of an OQL
             Heavily influenced by Hibernate QL
             Parsed by a top-down recursive descent parser LL(*),
              constructing an abstract syntax tree (AST)
             AST is then used to generate vendor dependent SQL


    $query = $em->createQuery(
            "SELECT u FROM MyProjectEntityUser u"
    );
    $users = $query->execute();




quarta-feira, 2 de junho de 2010
DoctrineORM
         Native Query
             Allow   you the possibility to fallback to the power of
                SQL without losing the ability to hydrate the data to
                your Entities
    $rsm = new DoctrineORMQueryResultSetMapping();
    $rsm->addEntityResult("MyProjectEntityUser", "u");
    $rsm->addFieldResult("u", "id", "id");
    $rsm->addFieldResult("u", "name", "name");

    $query = $em->createNativeQuery(
            "SELECT id, name FROM users WHERE username = ?", $rsm
    );
    $query->setParameter(1, "guilhermeblanco");

    $users = $query->getResult();



quarta-feira, 2 de junho de 2010
DoctrineORM
         QueryBuilder
             Builder implementation
             Building and execution are separated
             QueryBuilder cannot be executed; instead, get the
              Query instance from it and execute



    $qb = $em->createQueryBuilder()
        ->select("u")
        ->from("MyProjectEntityUser", "u");
    $users = $qb->getQuery()->execute();




quarta-feira, 2 de junho de 2010
DoctrineORM
         Doctrine supports different cache levels
             Metadata             cache
    $config->setMetadataCacheImpl($cacheDriver);

             Query          cache
    $config->setQueryCacheImpl($cacheDriver);

             Result         cache
    $config->setResultCacheImpl($cacheDriver);

    $query = $em->createQuery(
            "SELECT u FROM MyProjectEntityUser u"
    );
    $query->useResultCache(true, 3600, "my_custom_name");

quarta-feira, 2 de junho de 2010
DoctrineORM
         Console
             Uses Symfony 2 Console component
             Help developing with Doctrine
             Tasks available in all packages

    $helperSet = $cli->getHelperSet();
    $helperSet->set(
       new DoctrineDBALToolsConsoleHelperConnectionHelper(
         $em->getConnection()
       ), 'db'
    );
    $helperSet->set(
       new DoctrineORMToolsConsoleHelperEntityManagerHelper(
         $em
       ), 'em'
    );

    $cli->addCommands(array(...));

quarta-feira, 2 de junho de 2010
DoctrineORM
         Available Commands:
               DoctrineDBALToolsConsoleCommandRunSqlCommand
               DoctrineDBALToolsConsoleCommandImportCommand
               DoctrineORMToolsConsoleCommandClearCacheMetadataCommand
               DoctrineORMToolsConsoleCommandClearCacheResultCommand
               DoctrineORMToolsConsoleCommandClearCacheQueryCommand
               DoctrineORMToolsConsoleCommandSchemaToolCreateCommand
               DoctrineORMToolsConsoleCommandSchemaToolUpdateCommand
               DoctrineORMToolsConsoleCommandSchemaToolDropCommand
               DoctrineORMToolsConsoleCommandConvertDoctrine1SchemaCommand
               DoctrineORMToolsConsoleCommandConvertMappingCommand
               DoctrineORMToolsConsoleCommandGenerateRepositoriesCommand
               DoctrineORMToolsConsoleCommandGenerateEntitiesCommand
               DoctrineORMToolsConsoleCommandGenerateProxiesCommand
               DoctrineORMToolsConsoleCommandEnsureProductionSettingsCommand
               DoctrineORMToolsConsoleCommandValidateSchemaCommand
               DoctrineORMToolsConsoleCommandRunDqlCommand
quarta-feira, 2 de junho de 2010
Future
         DBAL
             QueryBuilder
             Finish MSSQL Server driver



         DQL
             Support for TYPE()
             Add multiple FROM Entities support
             Embedded Values



         ODM
             Extract DocumentManager interface
             Stabilize the MongoDB driver
             Implement other drivers (CouchDB, SimpleDB, ...)



quarta-feira, 2 de junho de 2010
Questions?
         Guilherme Blanco
             Contact              Info:

                     @guilhermeblanco

                     guilhermeblanco@php.net

                     http://www.facebook.com/guilhermeblanco

                     +55 16 9215.8480

         THANK YOU FOR YOUR PATIENCE!!! =)


quarta-feira, 2 de junho de 2010

Weitere ähnliche Inhalte

Was ist angesagt?

Zephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsZephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsMark Baker
 
Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)James Titcumb
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaPatrick Allaert
 
Yapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed PerlYapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed PerlHideaki Ohno
 
Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Nikita Popov
 
PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021Ayesh Karunaratne
 
Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objectsjulien pauli
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?Nikita Popov
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersLin Yo-An
 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalKent Ohashi
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Nikita Popov
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Lin Yo-An
 
Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)julien pauli
 
typemap in Perl/XS
typemap in Perl/XS  typemap in Perl/XS
typemap in Perl/XS charsbar
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Shinya Ohyanagi
 

Was ist angesagt? (20)

Zephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsZephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensions
 
Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 Verona
 
Yapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed PerlYapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed Perl
 
The new features of PHP 7
The new features of PHP 7The new features of PHP 7
The new features of PHP 7
 
Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8
 
PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021
 
Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objects
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP haters
 
Building Custom PHP Extensions
Building Custom PHP ExtensionsBuilding Custom PHP Extensions
Building Custom PHP Extensions
 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of Pedestal
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015
 
Short Introduction To "perl -d"
Short Introduction To "perl -d"Short Introduction To "perl -d"
Short Introduction To "perl -d"
 
Workshop unittesting
Workshop unittestingWorkshop unittesting
Workshop unittesting
 
Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)
 
typemap in Perl/XS
typemap in Perl/XS  typemap in Perl/XS
typemap in Perl/XS
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
 

Andere mochten auch

Doctrine 2.0: A evolução da persistência em PHP
Doctrine 2.0: A evolução da persistência em PHPDoctrine 2.0: A evolução da persistência em PHP
Doctrine 2.0: A evolução da persistência em PHPGuilherme Blanco
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmDesenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmGuilherme Blanco
 
PHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsPHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsGuilherme Blanco
 
PHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object CalisthenicsPHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object CalisthenicsGuilherme Blanco
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHPGuilherme Blanco
 

Andere mochten auch (10)

PHP, Daemons e Multimedia
PHP, Daemons e MultimediaPHP, Daemons e Multimedia
PHP, Daemons e Multimedia
 
Dependency injection
Dependency injectionDependency injection
Dependency injection
 
Doctrine 2.0: A evolução da persistência em PHP
Doctrine 2.0: A evolução da persistência em PHPDoctrine 2.0: A evolução da persistência em PHP
Doctrine 2.0: A evolução da persistência em PHP
 
Doctrine2 Seminário PHP
Doctrine2 Seminário PHPDoctrine2 Seminário PHP
Doctrine2 Seminário PHP
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmDesenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine Orm
 
PHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsPHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object Calisthenics
 
PHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object CalisthenicsPHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object Calisthenics
 
PHP 7
PHP 7PHP 7
PHP 7
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHP
 
Javascript para adultos
Javascript para adultosJavascript para adultos
Javascript para adultos
 

Ähnlich wie IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP

PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkG Woo
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest UpdatesIftekhar Eather
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionNate Abele
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiJérémy Derussé
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitsmueller_sandsmedia
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingTricode (part of Dept)
 
Go OO! - Real-life Design Patterns in PHP 5
Go OO! - Real-life Design Patterns in PHP 5Go OO! - Real-life Design Patterns in PHP 5
Go OO! - Real-life Design Patterns in PHP 5Stephan Schmidt
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Eric Hogue
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
 
Annotation Processing in Android
Annotation Processing in AndroidAnnotation Processing in Android
Annotation Processing in Androidemanuelez
 

Ähnlich wie IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP (20)

PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Solid principles
Solid principlesSolid principles
Solid principles
 
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching logging
 
Ejb3 Dan Hinojosa
Ejb3 Dan HinojosaEjb3 Dan Hinojosa
Ejb3 Dan Hinojosa
 
Libertyvasion2010
Libertyvasion2010Libertyvasion2010
Libertyvasion2010
 
Go OO! - Real-life Design Patterns in PHP 5
Go OO! - Real-life Design Patterns in PHP 5Go OO! - Real-life Design Patterns in PHP 5
Go OO! - Real-life Design Patterns in PHP 5
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Annotation processing
Annotation processingAnnotation processing
Annotation processing
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
PHP 5.3
PHP 5.3PHP 5.3
PHP 5.3
 
Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
Annotation Processing in Android
Annotation Processing in AndroidAnnotation Processing in Android
Annotation Processing in Android
 
Doctrine for NoSQL
Doctrine for NoSQLDoctrine for NoSQL
Doctrine for NoSQL
 
Doctrine and NoSQL
Doctrine and NoSQLDoctrine and NoSQL
Doctrine and NoSQL
 

Kürzlich hochgeladen

Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024SkyPlanner
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdfPedro Manuel
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfDianaGray10
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxUdaiappa Ramachandran
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPathCommunity
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UbiTrack UK
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 

Kürzlich hochgeladen (20)

Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdf
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 
20230104 - machine vision
20230104 - machine vision20230104 - machine vision
20230104 - machine vision
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptx
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation Developers
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 

IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP

  • 1. Guilherme Blanco, Yahoo! Doctrine 2 Enterprise Persistence Layer for PHP quarta-feira, 2 de junho de 2010
  • 2. Who am I?  10+ years web developer  Open Source evangelist  Works for Yahoo!  Contributes to...  ...Doctrine  ...Zend Framework  ...Symfony  ...PHP  etc  Likes to sing and also fish on spare time! =) quarta-feira, 2 de junho de 2010
  • 3. Who am I?  http://www.twitter.com/guilhermeblanco  http://www.facebook.com/guilhermeblanco quarta-feira, 2 de junho de 2010
  • 4. Doctrine 2 quarta-feira, 2 de junho de 2010
  • 5. Doctrine 2  PHP 5.3+  100% code rewritten  Fully namespaced code quarta-feira, 2 de junho de 2010
  • 6. Doctrine 2  Tools used:  phpUnit Unit testing  Phing Packaging and distribution  Symfony Components  YAML  Console  Sismo Continuous Integration  GIT Source version control  JIRA Issue tracking and management  Trac Timeline, source code & changeset viewer quarta-feira, 2 de junho de 2010
  • 7. Doctrine 2  Three main packages:  Common  DBAL  ORM quarta-feira, 2 de junho de 2010
  • 8. DoctrineCommon git@github.com:doctrine/common.git  Cache Drivers quarta-feira, 2 de junho de 2010
  • 9. DoctrineCommonCache  Supported Drivers:  APCCache $cacheDriver = new DoctrineCommonCacheApcCache();  MemcacheCache $memcache = new Memcache(); $memcache->addServer('memcache_host', 11211); $cacheDriver = new DoctrineCommonCacheMemcacheCache(); $cacheDriver->setMemcache($memcache);  XcacheCache $cacheDriver = new DoctrineCommonCacheXcacheCache(); quarta-feira, 2 de junho de 2010
  • 10. DoctrineCommonCache  Cache Drivers Interface: interface DoctrineCommonCacheCache { function setNamespace($namespace); function getIds(); function fetch($id); function contains($id); function save($id, $data, $lifeTime = 0); function delete($id); function deleteAll(); function deleteByRegex($regex); function deleteByPrefix($prefix); function deleteBySuffix($suffix); } quarta-feira, 2 de junho de 2010
  • 11. DoctrineCommon git@github.com:doctrine/common.git  Cache Drivers  Class Loader quarta-feira, 2 de junho de 2010
  • 12. DoctrineCommonClassLoader  Implements PSR #0  PSR = PHP Standards Recommendation  Technical Interoperability between libraries  Symfony, Zend Framework, Doctrine, Agavi, PEAR2/Pyrus, Lithium, Flow3, Solar, etc  Possible merge in PHP core: SplClassLoader  http://wiki.php.net/rfc/splclassloader quarta-feira, 2 de junho de 2010
  • 13. DoctrineCommonClassLoader  Usage: require_once '/path/to/lib/Doctrine/Common/ClassLoader.php'; $doctrineClassLoader = new DoctrineCommonClassLoader( 'Doctrine', '/path/to/lib/Doctrine' ); $doctrineClassLoader->register(); quarta-feira, 2 de junho de 2010
  • 14. DoctrineCommon git@github.com:doctrine/common.git  Cache Drivers  Class Loader  Collections quarta-feira, 2 de junho de 2010
  • 15. DoctrineCommonCollections  Solution inspired in java.util.Collection interface  Plain PHP arrays are hard to manipulate  ..but custom array implementations are not compatible with array_* functions  Heavily usage of Closures  User-land SplArray  Where are the PHP devs? quarta-feira, 2 de junho de 2010
  • 16. DoctrineCommon git@github.com:doctrine/common.git  Cache Drivers  Class Loader  Collections  Lexer  Annotations Parser quarta-feira, 2 de junho de 2010
  • 17. DoctrineCommonAnnotations  Java like Annotations  Define metadata information in classes  Reusable and highly extendable  Suppress missing PHP functionality  Again, where are the PHP devs?  RFC already written: http://wiki.php.net/rfc/annotations quarta-feira, 2 de junho de 2010
  • 18. DoctrineCommonAnnotations Annotations ::= Annotation {[ "*" ]* [Annotation]}* Annotation ::= "@" AnnotationName ["(" [Values] ")"] AnnotationName ::= QualifiedName | SimpleName | AliasedName QualifiedName ::= NameSpacePart "" {NameSpacePart ""}* SimpleName AliasedName ::= Alias ":" SimpleName NameSpacePart ::= identifier SimpleName ::= identifier Alias ::= identifier Values ::= Array | Value {"," Value}* Value ::= PlainValue | FieldAssignment PlainValue ::= integer | string | float | boolean | Array | Annotation FieldAssignment ::= FieldName "=" PlainValue FieldName ::= identifier Array ::= "{" ArrayEntry {"," ArrayEntry}* "}" ArrayEntry ::= Value | KeyValuePair KeyValuePair ::= Key "=" PlainValue Key ::= string | integer quarta-feira, 2 de junho de 2010
  • 19. DoctrineCommonAnnotations  Creating Annotations classes: final class DoctrineORMMappingEntity extends DoctrineCommonAnnotationsAnnotation { public $repositoryClass; }  Using Annotations: namespace MyProjectEntity; /** * @Entity(repositoryClass="RepositoryUserRepository") */ class User { // ... } quarta-feira, 2 de junho de 2010
  • 20. DoctrineCommonAnnotations  Reading Annotations: $reader = new DoctrineCommonAnnotationsAnnotationReader( new DoctrineCommonCacheArrayCache() ); $reader->setDefaultAnnotationNamespace( 'DoctrineORMMapping' ); $class = new ReflectionClass('MyProjectEntityUser'); $classAnnotations = $reader->getClassAnnotations($class); echo $classAnnotations['DoctrineORMMappingEntity'] ->repositoryClass; quarta-feira, 2 de junho de 2010
  • 21. DoctrineCommonAnnotations interface DoctrineCommonAnnotationsAnnotationReader { function setDefaultAnnotationNamespace($defaultNamespace); function setAnnotationNamespaceAlias($namespace, $alias); function getClassAnnotations(ReflectionClass $class); function getClassAnnotation(ReflectionClass $class, $annot); function getPropertyAnnotations(ReflectionProperty $property); function getPropertyAnnotation( ReflectionProperty $property, $annot ); function getMethodAnnotations(ReflectionMethod $method); function getMethodAnnotation(ReflectionMethod $method, $annot); } quarta-feira, 2 de junho de 2010
  • 22. DoctrineDBAL git@github.com:doctrine/dbal.git  Database Abstraction Layer built at the top of PDO and proprietary drivers  Supported drivers:  DB2  Microsoft SQL Server (pdo_sqlsrv & sqlsrv)  MySQL  PostgreSQL  Oracle  SQLite quarta-feira, 2 de junho de 2010
  • 23. DoctrineDBAL  Improved API for Database introspection and schema management  Hopefully it can be a defacto standard DBAL for PHP 5.3 in the future, like MDB2 for PEAR1  Inspired in ezcDatabase, MDB2 and Zend_Db  Maybe we can make this happen for PEAR2 quarta-feira, 2 de junho de 2010
  • 24. DoctrineDBAL interface DoctrineDBALConnection { // Data manipulation API /* Executes an SQL DELETE statement on a table. */ function delete($tableName, array $identifier); /* Executes an SQL UPDATE statement on a table. */ function update($tableName, array $data, array $identifier); /* Inserts a table row with specified data. */ function insert($tableName, array $data); /* Prepares an SQL statement. Returns a DBALStatement */ function prepare($statement); /* Applies a SQL statement and return # of affected rows. */ function exec($statement); // ... quarta-feira, 2 de junho de 2010
  • 25. DoctrineDBAL // Transaction API /* Returns the current transaction nesting level. */ function getTransactionNestingLevel(); /* Executes a function in a transaction. */ function transactional(Closure $func); /* Starts a transaction by suspending auto-commit mode. */ function beginTransaction(); /* Commits the current transaction. */ function commit(); /* Cancel any database changes done during current transaction. */ function rollback(); /* Check if current transaction is marked for rollback only. */ function isRollbackOnly(); // ... quarta-feira, 2 de junho de 2010
  • 26. DoctrineDBAL // Data fetching API /* Executes a SQL query and returns first row as an assoc array. */ function fetchAssoc($statement, array $params = array()); /* Executes a SQL query and returns first row as a numeric array. */ function fetchArray($statement, array $params = array()); /* Executes a SQL query and returns first column value of result. */ function fetchColumn( $statement, array $params = array(), $colnum = 0 ); /* Executes a SQL query and returns the result as an assoc array. */ function fetchAll($sql, array $params = array()); } quarta-feira, 2 de junho de 2010
  • 27. DoctrineDBALTypes  Centralized point to convert values  From Database to PHP  From PHP to Database  Database agnostic  Accessing specific DB dialect called Platform  Extendable quarta-feira, 2 de junho de 2010
  • 28. DoctrineDBALTypes  New DataType is just implement an abstract class: interface DoctrineDBALTypesType { function convertToDatabaseValue( $value, AbstractPlatform $platform ); function convertToPHPValue( $value, AbstractPlatform $platform ); function getSqlDeclaration( array $fieldDeclaration, AbstractPlatform $platform ); function getName(); function getBindingType(); } quarta-feira, 2 de junho de 2010
  • 29. DoctrineDBAL class MyProjectDataTypesMyObjectType extends DoctrineDBALTypesType { public function getSqlDeclaration( array $fieldDeclaration, AbstractPlatform $platform ) { return $platform->getClobTypeDeclarationSQL($fieldDeclaration); } public function convertToDatabaseValue( $value, AbstractPlatform $platform ) { return serialize($value); } public function convertToPHPValue($value, AbstractPlatform $platform) { $value = (is_resource($value)) ? stream_get_contents($value) : $value; return unserialize($value); } public function getName() { return "my-object"; } } quarta-feira, 2 de junho de 2010
  • 30. DoctrineDBALTypes  Finally, make Doctrine know about your DataType: DoctrineDBALTypesType::addType( "my-object", "MyProjectDataTypesMyObjectType" );  Then you can use it in your Entities! /** * @Entity * @Table(name="files") */ class File { // ... /** * @Column(type="my-object") */ protected $content; } quarta-feira, 2 de junho de 2010
  • 31. DoctrineDBAL  Creating a schema: $platform = $em->getConnection()->getDatabasePlatform(); $schema = new DoctrineDBALSchemaSchema(); $table = $schema->createTable("users"); $table->addColumn("id", "integer", array("unsigned" => true)); $table->addColumn("name", "string", array("length" => 32)); $table->setPrimaryKey(array("id")); // get queries to create this schema. $queries = $schema->toSql($platform); Array( 0 => 'CREATE TABLE users ( id INTEGER NOT NULL, name VARCHAR(32) NOT NULL, PRIMARY KEY("id") )' ) quarta-feira, 2 de junho de 2010
  • 32. DoctrineDBAL  Deleting a schema: // get queries to safely delete the schema. $queries = $schema->toDropSql($platform); Array( 0 => 'DROP TABLE users' )  It does the reverse of what ->toSql() does quarta-feira, 2 de junho de 2010
  • 33. DoctrineDBAL  Comparing schemas: $platform = $em->getConnection()->getDatabasePlatform(); $fromSchema = new DoctrineDBALSchemaSchema(); $table = $fromSchema->createTable("users"); $table->addColumn("id", "integer", array("unsigned" => true)); $table->addColumn("name", "string", array("length" => 32)); $table->setPrimaryKey(array("id")); quarta-feira, 2 de junho de 2010
  • 34. DoctrineDBAL  Comparing schemas: $platform = $em->getConnection()->getDatabasePlatform(); $toSchema = new DoctrineDBALSchemaSchema(); $table = $toSchema->createTable("users"); $table->addColumn("id", "integer", array("unsigned" => true)); $table->addColumn("name", "string", array("length" => 32)); $table->addColumn("email", "string", array("length" => 255)); $table->setPrimaryKey(array("id")); quarta-feira, 2 de junho de 2010
  • 35. DoctrineDBAL  Comparing schemas: $platform = $em->getConnection()->getDatabasePlatform(); $comparator = new DoctrineDBALSchemaComparator(); $schemaDiff = $comparator->compare($fromSchema, $toSchema); // queries to get from one to another schema. $queries = $schemaDiff->toSql($platform); Array( 0 => 'ALTER TABLE users ADD email VARCHAR(255) NOT NULL' ) quarta-feira, 2 de junho de 2010
  • 36. Insert Performance  Inserting 20 entries with Doctrine 2: for ($i = 0; $i < 20; $i++) { $user = new User(); $user->name = 'Guilherme Blanco'; $em->persist($user); } $start = microtime(0); $em->flush(); $end = microtime(0); echo $end - $start; quarta-feira, 2 de junho de 2010
  • 37. Insert Performance  Inserting 20 entries with raw PHP code: $start = microtime(0); for ($i = 0; $i < 20; $i++) { mysql_query( "INSERT INTO users (name) VALUES ('Guilherme Blanco')", $db_link ); } $end = microtime(0); echo $end - $start; quarta-feira, 2 de junho de 2010
  • 38. Insert Performance  We are not kidding here! =P Which one do you think it is faster?  Doctrine 2  Took: 0.0094 seconds  PHP code  Took: 0.0165 seconds  WTH?!?! Doctrine 2 is faster than raw PHP?  Itdoes a lot less, provides no features, no abstraction!  Answer is TRANSACTIONS! Doctrine 2 manages our transactions and efficiently executes all inserts in a single. quarta-feira, 2 de junho de 2010
  • 39. Insert Performance  Doctrine 2 *IS NOT* faster than raw PHP code  Simple developers oversights can cause significant performance problems! quarta-feira, 2 de junho de 2010
  • 40. Insert Performance  Inserting 20 entries with raw PHP code (revisited): $start = microtime(0); mysql_query("START TRANSACTION", $db_link); for ($i = 0; $i < 20; $i++) { mysql_query( "INSERT INTO users (name) VALUES ('Guilherme Blanco')", $db_link ); } mysql_query("COMMIT", $db_link); $end = microtime(0); echo $end - $start; quarta-feira, 2 de junho de 2010
  • 41. Insert Performance  Final performance information...  Doctrine 2  Took: 0.0094 seconds  PHP code  Took: 0.0165 seconds  PHP code (revisited)  Took: 0.0028 seconds  You can read more about this on Doctrine Blog  http://www.doctrine-project.org/blog/transactions-and-performance quarta-feira, 2 de junho de 2010
  • 42. DoctrineORM  What have we learned from Doctrine 1?  Persistence Layer != Domain Model  Focus on our key purpose, the Persistence Layer  “You’re doing it wrong!”  Kill magic quarta-feira, 2 de junho de 2010
  • 43. DoctrineORM  Performance comparison  Hydrating 5000 records  Doctrine 1.2: 4.3 seconds  Doctrine 2.0-DEV: 1.4 seconds  Hydrating 10000 records  Doctrine 2.0-DEV: 3.5 seconds  Twice records and still faster than Doctrine 1! quarta-feira, 2 de junho de 2010
  • 44. DoctrineORM  Why is it faster?  PHP 5.3 optimizations!  30% less resources usage, 20% faster  5.3-DEV (lazy bucket alloc, interned strings, runtime cache), Doctrine 2 can run 50% faster!  Better Hydration algorithm  Topological Sorting  Slim Entities  Killed magic aspects of Doctrine 1 quarta-feira, 2 de junho de 2010
  • 45. DoctrineORM  Why kill magic?  Eliminate the WTF/minute (WTF factor)  Hard to debug  Edge cases are hard to fix  Edge cases are hard to workaround  Everything works until you go outside the box  ...and magic is slow! I can prove it!  __set is ~87% slower than normal set  __get is ~150% slower than normal get quarta-feira, 2 de junho de 2010
  • 46. DoctrineORM  How we kill magic?  We call it OOP!  Object Composition  Inheritance  Aggregation  Containment  Encapsulation  etc quarta-feira, 2 de junho de 2010
  • 47. DoctrineORM  DataMapper instead of ActiveRecord  Heavily inspired by JSR-317, a.k.a. JPA v2.0  Java... WHAT?!?! #$@&*!  PHP still lacks of standards  PHP Standards Group can rescue us?!  Final 2.0.0 version expected for September 1st quarta-feira, 2 de junho de 2010
  • 48. DoctrineORM  Entities  Regular PHP class  Lightweight persistent domain object  Do not extend any base class!  Cannot be final or contain final methods  Two entities in a hierarchy of classes can not map property with the same name  Abstract and concrete classes can be Entities  Entities may extend non-entity classes as well as entity classes  Non-entity classes may also extend entity classes quarta-feira, 2 de junho de 2010
  • 49. DoctrineORM namespace Entity; /** * @Entity * @Table(name="users") */ class User { /** * @Id @GeneratedValue * @Column(type="integer") */ protected $id; /** * @Column(type="string", length=32) */ protected $name; // ... getters and setters } quarta-feira, 2 de junho de 2010
  • 50. DoctrineORM EntityUser: type: entity table: users id: id: type: integer generator: strategy: AUTO fields: name: type: string length: 32 quarta-feira, 2 de junho de 2010
  • 51. DoctrineORM <?xml version="1.0" encoding="UTF-8"?> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="EntityUser" table="users"> <id name="id" type="integer"> <generator strategy="AUTO"/> </id> <field name="name" type="string" length="50"/> </entity> </doctrine-mapping> quarta-feira, 2 de junho de 2010
  • 52. DoctrineORM  Column mapping  type  length  scale, precision  nullable  unique  name (DB)  options  columnDefinition /** * @Column(type="string", length=32, unique=true) */ protected $foo; quarta-feira, 2 de junho de 2010
  • 53. DoctrineORM  Identifier fields  Supports different strategies:  AUTO  SEQUENCE  TABLE  NONE /** * @Id @GeneratedValue(strategy="AUTO") * @Column(type="integer") */ protected $id; quarta-feira, 2 de junho de 2010
  • 54. DoctrineORM  Association fields  OneToOne /** @OneToOne(targetEntity="Shipping") */ private $shipping;  OneToMany  ManyToOne  ManyToMany /** * @ManyToMany(targetEntity="Group") * @JoinTable(name="users_groups", joinColumns={ * @JoinColumn(name="user_id", referencedColumnName="id") * }, inverseJoinColumns={ * @JoinColumn(name="group_id", referencedColumnName="id") * }) */ private $groups; quarta-feira, 2 de junho de 2010
  • 55. DoctrineORM  Inheritance  Concrete Table Inheritance  No irrelevant columns  No locking problems  Difficult to deal with Primary Keys  No relations in base class  Search on superclass means search in all tables (too much queries or a weird join)  Refactoring of fields means update a few or all table quarta-feira, 2 de junho de 2010
  • 56. DoctrineORM /** @MappedSuperclass */ class MappedSuperclassBase { /** @Column(type="string") */ protected $mapped; /** * @OneToOne(targetEntity="MappedSuperclassRelated") * @JoinColumn(name="related_id", referencedColumnName="id") */ protected $related; } /** @Entity @Table(name="users") */ class User extends MappedSuperclassBase { /** @Id @Column(type="integer") */ protected $id; /** @Column(type="string", length=32) */ protected $name; } quarta-feira, 2 de junho de 2010
  • 57. DoctrineORM CREATE TABLE users ( mapped TEXT NOT NULL, id INTEGER NOT NULL, name TEXT NOT NULL, related_id INTEGER DEFAULT NULL, PRIMARY KEY(id) ); quarta-feira, 2 de junho de 2010
  • 58. DoctrineORM  Inheritance  Single Table Inheritance  Only one table on database  No joins  Refactoring of fields do not change DB schema  Waste of space on database  Too many locks due to many accesses  No duplicated name of fields with different meaning quarta-feira, 2 de junho de 2010
  • 59. DoctrineORM namespace MyProjectEntity; /** * @Entity * @InheritanceType("SINGLE_TABLE") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({ * "user" = "User", "employee" = "Employee" * }) */ class User { // ... } /** @Entity */ class Employee extends User { // ... } quarta-feira, 2 de junho de 2010
  • 60. DoctrineORM  Inheritance  Class Table Inheritance  Easy to understand  DB space is optimized due to normalization  Direct relationship between Domain Model and database  Too many joins  Refactoring of fields need a database schema update  Supertype table accessed a lot, may be in lock mode quarta-feira, 2 de junho de 2010
  • 61. DoctrineORM namespace MyProjectEntity; /** * @Entity * @InheritanceType("JOINED") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({ * "user" = "User", "employee" = "Employee" * }) */ class User { // ... } /** @Entity */ class Employee extends User { // ... } quarta-feira, 2 de junho de 2010
  • 62. DoctrineORM  Proxies  Lazy-load Entity data  Provide the possibility to get an Entity reference without database access  Can be generated on-the-fly (during script execution) or via a Console tool $proxyUser = $em->getReference("User", 1); quarta-feira, 2 de junho de 2010
  • 63. DoctrineORM  EntityManager  Central point of ORM functionality  Employes Transaction Write Behind strategy that delays executions of SQL statements  ...this means, efficiency!  ...and also means that write locks are quickly released!  Internally, it uses a UnitOfWork to keep track of your objects state quarta-feira, 2 de junho de 2010
  • 64. DoctrineORM interface DoctrineORMEntityManager { // Transaction API /* Starts a transaction on the underlying database connection. */ function beginTransaction(); /* Commits a transaction on underlying database connection. */ function commit(); /* Flushes all changes to queued objects to the database. */ function flush(); /* Performs a rollback on the underlying database connection. */ function rollback(); /* Executes a function in a transaction. */ function transactional(Closure $func); // ... quarta-feira, 2 de junho de 2010
  • 65. DoctrineORM // Query API /* Creates a new Query object. */ function createQuery($dql); /* Creates a native SQL query. */ function createNativeQuery( $sql, DoctrineORMQueryResultSetMapping $rsm ); /* Create a QueryBuilder instance. */ function createQueryBuilder(); /* Finds an Entity by its identifier. */ function find($entityName, $identifier, $lockMode = LockMode::NONE, $lockVersion = null); /* Gets a reference to the entity identified by the given type and identifier without actually loading it. */ function getReference($entityName, $identifier); // ... quarta-feira, 2 de junho de 2010
  • 66. DoctrineORM // Object Manipulation API /* Tells EntityManager to make instance managed and persistent. */ function persist($entity); /* Removes an entity instance. */ function remove($entity); /* Refresh state of entity from database, overrides changes. */ function refresh($entity); /* Detaches an entity from the EntityManager. */ function detach($entity); /* Merges state of detached entity into persistence context. */ function merge($entity); // ... quarta-feira, 2 de junho de 2010
  • 67. DoctrineORM // Repository, Configuration, EventManager, etc /* Gets the EventManager used by the EntityManager. */ function getEventManager(); /* Gets the Configuration used by the EntityManager. */ function getConfiguration(); /* Gets the repository for an entity class. */ function getRepository($entityName); /* Returns the metadata for a class. */ function getClassMetadata($className); /* Gets database connection object used by the EntityManager. */ function getConnection(); } quarta-feira, 2 de junho de 2010
  • 68. DoctrineORM  Working with Entities in EntityManager  Creating an EntityManager $config = new DoctrineORMConfiguration(); $config->setMetadataCacheImpl($cacheDriver); $config->setQueryCacheImpl($cacheDriver); $config->setProxyDir("/path/to/MyProject/Proxies"); $config->setProxyNamespace("MyProjectProxies"); $connectionOptions = array( "driver" => "pdo_sqlite", "path" => "database.sqlite" ); // Creating the EntityManager $em = DoctrineORMEntityManager::create( $connectionOptions, $config ); quarta-feira, 2 de junho de 2010
  • 69. DoctrineORM  Working with Entities in EntityManager  Persisting Entities try { $em->transactional(function ($em) { $user = new MyProjectEntityUser(); $user->name = "Guilherme Blanco"; $em->persist($user); }); } catch (Exception $e) { // ... } quarta-feira, 2 de junho de 2010
  • 70. DoctrineORM  Working with Entities in EntityManager  Updating Entities try { $em->transactional(function ($em) { $user = $em->find("MyProjectEntityUser", 1); $user->name = "Benjamin Eberlei"; $em->persist($user); }); } catch (Exception $e) { // ... } quarta-feira, 2 de junho de 2010
  • 71. DoctrineORM  Working with Entities in EntityManager  Deleting Entities try { $em->transactional(function ($em) { $user = $em->getReference("MyProjectEntityUser", 1); $em->remove($user); }); } catch (Exception $e) { // ... } quarta-feira, 2 de junho de 2010
  • 72. DoctrineORM  Doctrine Query Language (DQL)  Implementation of an OQL  Heavily influenced by Hibernate QL  Parsed by a top-down recursive descent parser LL(*), constructing an abstract syntax tree (AST)  AST is then used to generate vendor dependent SQL $query = $em->createQuery( "SELECT u FROM MyProjectEntityUser u" ); $users = $query->execute(); quarta-feira, 2 de junho de 2010
  • 73. DoctrineORM  Native Query  Allow you the possibility to fallback to the power of SQL without losing the ability to hydrate the data to your Entities $rsm = new DoctrineORMQueryResultSetMapping(); $rsm->addEntityResult("MyProjectEntityUser", "u"); $rsm->addFieldResult("u", "id", "id"); $rsm->addFieldResult("u", "name", "name"); $query = $em->createNativeQuery( "SELECT id, name FROM users WHERE username = ?", $rsm ); $query->setParameter(1, "guilhermeblanco"); $users = $query->getResult(); quarta-feira, 2 de junho de 2010
  • 74. DoctrineORM  QueryBuilder  Builder implementation  Building and execution are separated  QueryBuilder cannot be executed; instead, get the Query instance from it and execute $qb = $em->createQueryBuilder() ->select("u") ->from("MyProjectEntityUser", "u"); $users = $qb->getQuery()->execute(); quarta-feira, 2 de junho de 2010
  • 75. DoctrineORM  Doctrine supports different cache levels  Metadata cache $config->setMetadataCacheImpl($cacheDriver);  Query cache $config->setQueryCacheImpl($cacheDriver);  Result cache $config->setResultCacheImpl($cacheDriver); $query = $em->createQuery( "SELECT u FROM MyProjectEntityUser u" ); $query->useResultCache(true, 3600, "my_custom_name"); quarta-feira, 2 de junho de 2010
  • 76. DoctrineORM  Console  Uses Symfony 2 Console component  Help developing with Doctrine  Tasks available in all packages $helperSet = $cli->getHelperSet(); $helperSet->set( new DoctrineDBALToolsConsoleHelperConnectionHelper( $em->getConnection() ), 'db' ); $helperSet->set( new DoctrineORMToolsConsoleHelperEntityManagerHelper( $em ), 'em' ); $cli->addCommands(array(...)); quarta-feira, 2 de junho de 2010
  • 77. DoctrineORM  Available Commands:  DoctrineDBALToolsConsoleCommandRunSqlCommand  DoctrineDBALToolsConsoleCommandImportCommand  DoctrineORMToolsConsoleCommandClearCacheMetadataCommand  DoctrineORMToolsConsoleCommandClearCacheResultCommand  DoctrineORMToolsConsoleCommandClearCacheQueryCommand  DoctrineORMToolsConsoleCommandSchemaToolCreateCommand  DoctrineORMToolsConsoleCommandSchemaToolUpdateCommand  DoctrineORMToolsConsoleCommandSchemaToolDropCommand  DoctrineORMToolsConsoleCommandConvertDoctrine1SchemaCommand  DoctrineORMToolsConsoleCommandConvertMappingCommand  DoctrineORMToolsConsoleCommandGenerateRepositoriesCommand  DoctrineORMToolsConsoleCommandGenerateEntitiesCommand  DoctrineORMToolsConsoleCommandGenerateProxiesCommand  DoctrineORMToolsConsoleCommandEnsureProductionSettingsCommand  DoctrineORMToolsConsoleCommandValidateSchemaCommand  DoctrineORMToolsConsoleCommandRunDqlCommand quarta-feira, 2 de junho de 2010
  • 78. Future  DBAL  QueryBuilder  Finish MSSQL Server driver  DQL  Support for TYPE()  Add multiple FROM Entities support  Embedded Values  ODM  Extract DocumentManager interface  Stabilize the MongoDB driver  Implement other drivers (CouchDB, SimpleDB, ...) quarta-feira, 2 de junho de 2010
  • 79. Questions?  Guilherme Blanco  Contact Info:  @guilhermeblanco  guilhermeblanco@php.net  http://www.facebook.com/guilhermeblanco  +55 16 9215.8480  THANK YOU FOR YOUR PATIENCE!!! =) quarta-feira, 2 de junho de 2010