SlideShare ist ein Scribd-Unternehmen logo
1 von 42
Downloaden Sie, um offline zu lesen
Jornadas Symfony                               5 y 6 de julio 2010
                                               Universitat Jaume I, Castellón
http://decharlas.uji.es/symfony

organizan                         patrocinan




colaboran
Doctrine
          Nacho Martín




                                  5 y 6 de julio 2010
Jornadas Symfony                  Universitat Jaume I, Castellón
http://decharlas.uji.es/symfony
¿Qué es Doctrine?

            ●
             Object Relational Mapper hecho para
            PHP >=5.2.3 (Doctrine 2.0 PHP >5.3)

            ●
                   Basado en Hibernate (Java)

            ●
                   ¿Y Propel?




Jornadas Symfony                                http://decharlas.uji.es/symfony
Componentes




Jornadas Symfony         http://decharlas.uji.es/symfony
Activación
           //config/ProjectConfiguration.class.php
           public function setup()
           {
             $this->enablePlugins(array('sfDoctrinePlugin'));
             $this->disablePlugins(array('sfPropelPlugin'));
           }

           #config/databases.yml
           all:
            doctrine:
               class: sfDoctrineDatabase
               param:
                 dsn: 'mysql:host=localhost;dbname=midb'
                 username: usuario
                 password: secreto

Jornadas Symfony                                           http://decharlas.uji.es/symfony
Una aplicación de ejemplo

                      ●
                          Lista ToDo

                      ●
                          Con items (one-many)

                      ●
                          Y tags (many-many)




Jornadas Symfony                       http://decharlas.uji.es/symfony
El esquema YAML
  Todo:
   actAs:
    Timestampable: ~
   columns:
    name: { type: string(255), notnull: true}
    description: { type: string(1024) }
   relations:
    Tags: { class: Tag, refClass: TodoTag, local: todo_id, foreign: tag_id, foreignAlias: Todos}

  Item:
    actAs:
     Timestampable: ~
    columns:
     name: { type: string(255) }
     text: { type: string(4000) }
     todo_id: { type: integer, notnull: true }
    relations:
     Todo: { class: Todo, onDelete: CASCADE, local: todo_id, foreign: id, foreignAlias: items }

  TodoTag:
   columns:
    tag_id: { type: integer, primary: true }
    todo_id: { type: integer, primary: true }
   relations:
    Tag: { onDelete: CASCADE, local: tag_id, foreign: id }
    Todo: { onDelete: CASCADE, local: todo_id, foreign: id }

  Tag:
   columns:
    name: { type: string(255) }

Jornadas Symfony                                                                                   http://decharlas.uji.es/symfony
El modelo (columnas)
    abstract class BaseTodo extends sfDoctrineRecord
    {
      public function setTableDefinition()
      {
         $this->setTableName('todo');
         $this->hasColumn('name', 'string', 255, array(
            'type' => 'string',
            'notnull' => true,
            'length' => '255',
            ));
         $this->hasColumn('description', 'string', 1024, array(
            'type' => 'string',
            'length' => '1024',
            ));
      }


Jornadas Symfony                                     http://decharlas.uji.es/symfony
El modelo (relaciones)
            public function setUp()
           {
             parent::setUp();
             $this->hasMany('Tag as Tags', array(
                 'refClass' => 'TodoTag',
                 'local' => 'todo_id',
                 'foreign' => 'tag_id'));

                   $this->hasMany('Item as items', array(
                      'local' => 'id',
                      'foreign' => 'todo_id'));

                   $this->hasMany('TodoTag', array(
                      'local' => 'id',
                      'foreign' => 'tag_id'));

               //Behaviour
               $timestampable0 = new Doctrine_Template_Timestampable();
               $this->actAs($timestampable0);
           }
      }



Jornadas Symfony                                                  http://decharlas.uji.es/symfony
Fixtures (Doctrine 1)
            Todo:
             denver:
              name: Cosas que hacer en Denver
              description: Cuando hayamos muerto

            Item:
              gambas:
               name: Comer gambas
               Todo: denver
              gangsters:
               name: Cosas de gangsters
               Todo: denver

            Tag:
             turismo:
              name: Turismo gangsteril
              Todos: [denver]

Jornadas Symfony                                   http://decharlas.uji.es/symfony
DQL

           ●
               Simplifica SQL y es portable

           ●
               Incorpora POO a SQL




Jornadas Symfony                              http://decharlas.uji.es/symfony
DQL
          $q = Doctrine_Query::create()
             ->select('l.*, i.name, t.name')
             ->from('Todo l')
             ->innerJoin('l.Items i')
             ->leftJoin('l.Tags t');
         echo $q->getSqlQuery();


       SELECT t.id AS t__id, t.name AS t__name, t.description
       AS t__description, t.created_at AS t__created_at,
       t.updated_at AS t__updated_at, i.id AS i__id, i.name AS
       i__name, t2.id AS t2__id, t2.name AS t2__name FROM
       todo t INNER JOIN item i ON t.id = i.todo_id LEFT JOIN
       todo_tag t3 ON (t.id = t3.todo_id) LEFT JOIN tag t2 ON
       t2.id = t3.tag_id


Jornadas Symfony                                     http://decharlas.uji.es/symfony
Objetos
           Métodos de acceso y manipulación

           $list = new Todo();

       //Manipulación
     1 $list->name = "Cosas que hacer en Denver";
     2 $list['name'] = "Cosas que hacer en Denver";
     3 $list->set('name', "Cosas que hacer en Denver");

       //Acceso
     1 echo $list->name;
     2 echo $list['name']; //Recomendado (hidratación)
     3 echo $list->get('name');



Jornadas Symfony                                    http://decharlas.uji.es/symfony
Hidratación (I)
           ●
             En objetos
           ●
             En arrays (más rápido)
           ●
             Scalar
           ●
             Single Scalar
           ●
             Bajo demanda
           ●
             …


           ¿No es suficiente?
           ¡Escribe el tuyo!




Jornadas Symfony                      http://decharlas.uji.es/symfony
Hidratación (II)
  $q = Doctrine_Query::create()
   ->from('Todo l')
   ->innerJoin('l.Items i');

  $lists = $q->execute(); //Record
  echo $lists[0]['name'];




Jornadas Symfony                     http://decharlas.uji.es/symfony
Hidratación (II)
                                       Array
  $q = Doctrine_Query::create()        (
   ->from('Todo l')                       [0] => Array
                                             (
   ->innerJoin('l.Items i');
                                               [id] => 1
                                               [name] => Cosas que hacer en Denver
  $lists = $q->execute(); //Record             [description] => Cuando hayamos muerto
  echo $lists[0]['name'];                      [created_at] => 2010-06-22 23:55:02
                                               [updated_at] => 2010-06-22 23:55:02
                                               [Items] => Array
  $lists = $q->fetchArray(); //Array              (
  echo $lists[0]['name'];                            [0] => Array
  //O bien $q->execute(array(),                         (
  Doctrine::HYDRATE_ARRAY);                               [id] => 1
                                                          [name] => Comer gambas
  print_r($lists);                                        [text] =>
                                                          [todo_id] => 1
                                                          [created_at] => 2010-06-22 23:55:02
                                                          [updated_at] => 2010-06-22 23:55:02
                                                        )

                                                     [1] => Array
                                                        (…)
                                                 )
                                            )
                                       )




Jornadas Symfony                                                            http://decharlas.uji.es/symfony
Hidratación (III)

         ●
           El acceso por arrays funciona en los dos
         métodos de hidratación
         ●
           La hidratación por arrays es más eficiente
         si solo queremos consultar datos directos
         de la BD
         ●
           fetchArray() es un alias de execute() con
         la hidratación por array
         ●
           Uso de foreach, count(), isset(), unset()


Jornadas Symfony                              http://decharlas.uji.es/symfony
Definiendo setters/getters
               class Todo extends BaseTodo
               {
                 //Nuevo getter
                 public function getDescriptionHtml()
                 {
                   return Markdown::parse(htmlspecialchars(
                                          $this->description));
                 }

                 //Sobrecarga del setter
                 public function setDescription($description)
                 {
                   return $this->_set('description',
               Markdown::parse(htmlspecialchars($description)));
                 }
               }

Jornadas Symfony                                          http://decharlas.uji.es/symfony
Relaciones
                             $list = new Todo();
                             $list['name'] = "Libros para este verano";
                             $list->Items[]->name = "Hablemos de Langostas";
                             $list->save();

                             //Usando link()
   ●
    Las relaciones son       $item = new Item();
   intuitivas                $item['name'] = "La broma infinita";
                             $item->link('Todo',array($list['id']));
   ●
    Siempre podemos recurrir $item->save();
   a DQL                     //Borrar
                             $list->Items[0]->delete();
   ●
    Pero en DQL no se
                             //Siempre nos quedará DQL
   ejecutarán preDelete(),   $q = Doctrine_Query::create()
   postDelete()... (!)         ->delete('Item')
                               ->addWhere('todo_id = ?', $list['id'])
                               ->whereIn('name', array($item['name'], 'otro
                                           nombre'));
                             $q->execute();



Jornadas Symfony                                                  http://decharlas.uji.es/symfony
Many to many              Array
      $q = Doctrine_Query::create() (
                                       [0] => Array
        ->from('Todo l')
                                          (
        ->leftJoin('l.TodoTag tt')          [id] => 27
        ->leftJoin('tt.Tag t');             [name] => Cosas que hacer en Denver
      print_r($q->fetchArray());            [description] => Cuando hayamos muerto
                                            [created_at] => 2010-06-23 20:35:41
      //Equivalente                         [updated_at] => 2010-06-23 20:35:41
      $q = Doctrine_Query::create()         [TodoTag] => Array
        ->from('Todo l')                       (
        ->leftJoin('l.Tags t');                   [0] => Array
      print_r($q->fetchArray());                     (
                                                        [tag_id] => 2
                                                        [todo_id] => 27
      ●
        Podemos “olvidarnos”                            [Tag] => Array
                                                           (
      de la tabla intermedia                                 [id] => 2
                                                             [name] => Turismo
                                                           )
                                                     )
                                               )
                                          )
                                    )



Jornadas Symfony                                                      http://decharlas.uji.es/symfony
Mucha tela que cortar
           ●
             Behaviours
           ●
             Validadores
           ●
             Migraciones
           ●
             Herencia
           ●
             Caché
           ●
             Event listeners
           ●
             …




Jornadas Symfony                   http://decharlas.uji.es/symfony
Mucha tela que cortar
           ●
             Behaviours
           ●
             Validadores
           ●
             Migraciones
           ●
             Herencia
           ●
             Caché
           ●
             Event listeners
           ●
             …




         ¿Pero y Doctrine2?
                               Veamos Doctrine2
Jornadas Symfony                                  http://decharlas.uji.es/symfony
Doctrine2

           ●
             Reescritura completa del código para
           PHP 5.3
           ●
             Mejoras importantes de rendimiento
           ●
             Menos magia
           ●
             Caché mejorada
           ●
             Entidades




Jornadas Symfony                              http://decharlas.uji.es/symfony
Entidades (I)
    <?php

    namespace Entities;

    /** @Entity @Table(name="usuarios") */
    class Usuario
    {
        /**
         * @Id @Column(type="integer")
         * @GeneratedValue(strategy="AUTO")
         */
        private $id;
        /** @Column(type="string", length=50) */
        private $nombre;
        /**
         * @OneToOne(targetEntity="Direccion")
         * @JoinColumn(name="direccion_id", referencedColumnName="id")
         */
        private $direccion;


      DocBlock Annotations
Jornadas Symfony                                             http://decharlas.uji.es/symfony
Entidades (II)
              public function getId()
              {
                  return $this->id;
              }

              public function getNombre()
              {
                  return $this->nombre;
              }

              public function setNombre($nombre)
              {
                  $this->nombre = $nombre;
              }

              public function getDireccion()
              {
                  return $this->direccion;
              }

              public function setDireccion(Direccion $direccion)
              {
                  if ($this->direccion !== $direccion) {
                      $this->direccion = $direccion;
                      $direccion->setUsuario($this);
                  }
              }
       }

Jornadas Symfony                                                   http://decharlas.uji.es/symfony
Entidades (III)
           ●
             No descienden de ninguna clase, están
           “separadas” del ORM, aunque mapeadas
           por él
           ●
             Menos magia. Es más fácil entender qué
           está pasando
           ●
             Más rápidas
           ●
             Herencia
           ●
             Gestionadas por el Entity Manager
           ●
             Sí, se pueden escribir en YAML y XML ;)


Jornadas Symfony                             http://decharlas.uji.es/symfony
Fixtures
             $em = $this->getEntityManager();

             $user1 = new ModelsUsuario();
             $user1->nombre = 'Nacho';



         ●
           Adiós al YAML. Se escriben en PHP
         ●
           ¿Por qué?
                   ●
                     Es más rápido cargarlas
                   ●
                     El código para tratar fixtures en YAML introdujo muchos
                   bugs en el pasado




Jornadas Symfony                                                http://decharlas.uji.es/symfony
persist() y flush()
                   $user = new EntitiesUsuario;
                   $user->setNombre('Nacho');
                   $entitymanager->persist($user);
                   $entitymanager->flush();



           ●
             Atención al uso de espacios de nombre
           ●
             Persist “marca” el objeto para guardar
           ●
             Flush ejecuta la unidad de trabajo



Jornadas Symfony                                     http://decharlas.uji.es/symfony
Rendimiento (I)
          for ($i=0; $i<1000; $i++){
            $user = new EntitiesUsuario;
            $user->setNombre('Nacho');
            $em->persist($user);
          }
          $inicio = microtime(true);
          $em->flush();
          $final = microtime(true);
          echo $final-$inicio."n";    0.377s
          //////////////////////////
          $inicio = microtime(true);
          for ($i=0; $i<1000; $i++){
            mysql_query("INSERT INTO usuarios (nombre) VALUES
          ('Nacho')", $link);
          }

                                       41.4s
          $final = microtime(true);
          echo $final-$inicio."n";



Jornadas Symfony                                          http://decharlas.uji.es/symfony
Rendimiento (II)
           ●
             Doctrine2 gestiona las transacciones por
           nosotros
           ●
             Así que es más rápido que código
           PHP+SQL mal optimizado
           ●
             (Por supuesto usar transacciones en
           PHP+SQL es más rápido que Doctrine2)
           ●
             También podemos controlar las
           transacciones nosotros



Jornadas Symfony                               http://decharlas.uji.es/symfony
Eventos Lifecycle
           ●
             pre/postRemove
           ●
             pre/postPersist
           ●
             pre/postUpdate
           ●
             postLoad : carga desde BD
           ●
             loadClassMetadata : carga desde metadatos
           (annotations, yaml, xml)
           ●
             onFlush
               /** @Entity @HasLifecycleCallbacks */
               class Usuario
               {
                 //(...)
                 /** @PostPersist */
                   public function doAlgoOnPostPersist()
                   {
                      $this->nombre = 'Me han cambiado en el postpersist';
                   }

Jornadas Symfony                                                             http://decharlas.uji.es/symfony
Behaviours (I)
            En Doctrine2 son código normal de PHP que
           extiende la funcionalidad base de las entidades
          /** @HasLifecycleCallbacks */
          class BlogPost
          {
             //(...)
             public function __construct()
             {
                $this->created = $this->updated = new DateTime("now");
             }

               /**
                * @PreUpdate
                */
               public function updated()
               {
                  $this->updated = new DateTime("now");
               }
          }


Jornadas Symfony                                                   http://decharlas.uji.es/symfony
Behaviours (II)
            ¿Pero cómo hacer el código reutilizable entre
           entidades?
             Usando interfaces, eventos y código PHP
            orientado a objetos
             Ejemplos:

               http://github.com/guilhermeblanco/Doctrine2-Sluggable-Functional-Behavior

               http://github.com/guilhermeblanco/Doctrine2-Hierarchical-Structural-Behavior

               http://www.doctrine-project.org/blog/doctrine2-versionable




Jornadas Symfony                                                                    http://decharlas.uji.es/symfony
Migraciones (I)
             Hacen el esquema versionable




             BD (antes)                     BD (después)




              Esquema                        Fichero de
                                             migración
Jornadas Symfony                                 http://decharlas.uji.es/symfony
Migraciones (I)
             Hacen el esquema versionable




              BD (antes)                BD (después)
                           Comparar




              Esquema                       Fichero de
                                            migración
Jornadas Symfony                                http://decharlas.uji.es/symfony
Migraciones (I)
             Hacen el esquema versionable




              BD (antes)                BD (después)
                           Comparar
                                       Generar


              Esquema                        Fichero de
                                             migración
Jornadas Symfony                                 http://decharlas.uji.es/symfony
Migraciones (I)
             Hacen el esquema versionable




              BD (antes)                BD (después)
                           Comparar
                                       Generar


              Esquema                        Fichero de
                                             migración
Jornadas Symfony                                 http://decharlas.uji.es/symfony
Migraciones (I)
             Hacen el esquema versionable

                                      Migrar


              BD (antes)                  BD (después)
                           Comparar
                                         Generar


              Esquema                          Fichero de
                                               migración
Jornadas Symfony                                   http://decharlas.uji.es/symfony
Migraciones (II)
             Aspecto de un fichero de migración
        class Version20100416130401 extends AbstractMigration
        {
           public function up(Schema $schema)
           {
             $table = $schema->createTable('users');
             $table->addColumn('username', 'string');
             $table->addColumn('password', 'string');
           }

              public function down(Schema $schema)
              {
                $schema->dropTable('users');
              }
        }

Jornadas Symfony                                     http://decharlas.uji.es/symfony
Migraciones (III)
             Gestionadas desde la consola:
           ●
               Diff: tras cambiar una entidad, genera la
           migración necesaria para cambiar la BD
           ●
             Dry-run: muestra el SQL para cerciorarnos de
           que es lo que esperamos
           ●
             Status: muestra en qué estado (versión,
           migraciones posibles, fecha...) estamos
           ●
             Migrate: ejecuta la migración (hacia adelante o
           hacia atrás → revertir)
           ●
             Write-sql: en lugar de migrar, escribe el SQL a
           un fichero

Jornadas Symfony                                           http://decharlas.uji.es/symfony
MongoDB (ODM)

           ●
            El ODM tiene el mismo aspecto que el ORM
           (métodos parecidos, Entidad → Documento,
           EntityManager → DocumentManager,...)
           ●
            Mañana hay una charla sobre MongoDB y
           Symfony ;)




Jornadas Symfony                               http://decharlas.uji.es/symfony
¿Preguntas?

                     Si surgen más tarde ;) :
                    nitram.ohcan@gmail.com
                        twitter:@nacmartin
                     http://nacho-martin.com



Jornadas Symfony                                http://decharlas.uji.es/symfony

Weitere ähnliche Inhalte

Was ist angesagt?

Curso Javascript profesionales
Curso Javascript profesionalesCurso Javascript profesionales
Curso Javascript profesionalesRedradix
 
Java clases dictadas
Java clases dictadasJava clases dictadas
Java clases dictadasGaloGabriel
 
02 python Programación orientada a objetos y funcional
02 python Programación orientada a objetos y funcional02 python Programación orientada a objetos y funcional
02 python Programación orientada a objetos y funcionalJuan Rodríguez
 
Clase6 collections
Clase6 collectionsClase6 collections
Clase6 collectionsjorg_marq
 
Java Applet:::Pelota que rebota en un recinto.
Java Applet:::Pelota que rebota en un recinto.Java Applet:::Pelota que rebota en un recinto.
Java Applet:::Pelota que rebota en un recinto.jubacalo
 
Java::Acceso a Bases de Datos
Java::Acceso a Bases de DatosJava::Acceso a Bases de Datos
Java::Acceso a Bases de Datosjubacalo
 
Sincronizar Threads
Sincronizar ThreadsSincronizar Threads
Sincronizar Threadsjubacalo
 
Java ArrayList Iterator
Java ArrayList IteratorJava ArrayList Iterator
Java ArrayList Iteratorjubacalo
 
Curso Drupal. Creacion de modulos en Drupal
Curso Drupal. Creacion de modulos en DrupalCurso Drupal. Creacion de modulos en Drupal
Curso Drupal. Creacion de modulos en DrupalMediaglobe Innova
 
Introducción a prototype javascript
Introducción a prototype javascriptIntroducción a prototype javascript
Introducción a prototype javascriptaitorgr
 

Was ist angesagt? (20)

Clase 7 objetos globales de javaScript
Clase 7 objetos globales de javaScriptClase 7 objetos globales de javaScript
Clase 7 objetos globales de javaScript
 
Clase 5 funciones en javaScript
Clase 5 funciones en javaScriptClase 5 funciones en javaScript
Clase 5 funciones en javaScript
 
Clase 6 objetos de javaScript
Clase 6 objetos de javaScriptClase 6 objetos de javaScript
Clase 6 objetos de javaScript
 
Taller ruby
Taller rubyTaller ruby
Taller ruby
 
Curso Javascript profesionales
Curso Javascript profesionalesCurso Javascript profesionales
Curso Javascript profesionales
 
Algoritmo BUG2 - Planificacion trayectorias
Algoritmo BUG2 - Planificacion trayectoriasAlgoritmo BUG2 - Planificacion trayectorias
Algoritmo BUG2 - Planificacion trayectorias
 
3 Introducción al lenguaje PHP
3 Introducción al lenguaje PHP3 Introducción al lenguaje PHP
3 Introducción al lenguaje PHP
 
Java clases dictadas
Java clases dictadasJava clases dictadas
Java clases dictadas
 
02 python Programación orientada a objetos y funcional
02 python Programación orientada a objetos y funcional02 python Programación orientada a objetos y funcional
02 python Programación orientada a objetos y funcional
 
Clase6 collections
Clase6 collectionsClase6 collections
Clase6 collections
 
Java Applet:::Pelota que rebota en un recinto.
Java Applet:::Pelota que rebota en un recinto.Java Applet:::Pelota que rebota en un recinto.
Java Applet:::Pelota que rebota en un recinto.
 
Introduccion lenguaje java
Introduccion lenguaje javaIntroduccion lenguaje java
Introduccion lenguaje java
 
Java::Acceso a Bases de Datos
Java::Acceso a Bases de DatosJava::Acceso a Bases de Datos
Java::Acceso a Bases de Datos
 
Sincronizar Threads
Sincronizar ThreadsSincronizar Threads
Sincronizar Threads
 
Semana 1 Estructuras de Control en Java
Semana 1   Estructuras de Control en JavaSemana 1   Estructuras de Control en Java
Semana 1 Estructuras de Control en Java
 
Tutorial de php
Tutorial de phpTutorial de php
Tutorial de php
 
Semana 4 Introduccion Javascript
Semana 4   Introduccion JavascriptSemana 4   Introduccion Javascript
Semana 4 Introduccion Javascript
 
Java ArrayList Iterator
Java ArrayList IteratorJava ArrayList Iterator
Java ArrayList Iterator
 
Curso Drupal. Creacion de modulos en Drupal
Curso Drupal. Creacion de modulos en DrupalCurso Drupal. Creacion de modulos en Drupal
Curso Drupal. Creacion de modulos en Drupal
 
Introducción a prototype javascript
Introducción a prototype javascriptIntroducción a prototype javascript
Introducción a prototype javascript
 

Andere mochten auch

RoHS 2 como dar cumplimiento a los requisitos de la directiva
RoHS 2 como dar cumplimiento a los requisitos de la directivaRoHS 2 como dar cumplimiento a los requisitos de la directiva
RoHS 2 como dar cumplimiento a los requisitos de la directivaJoan Tarruell
 
11108131 王廷瑜
11108131 王廷瑜11108131 王廷瑜
11108131 王廷瑜廷瑜 王
 
Érase una vez un reino llamado La Marca del mundo 2.0
Érase una vez un reino llamado La Marca del mundo 2.0Érase una vez un reino llamado La Marca del mundo 2.0
Érase una vez un reino llamado La Marca del mundo 2.0Alejandro Navarro Segovia
 
​Capacitación de QNAP Soluciones de Videovigilancia y Almacenamiento
​Capacitación de QNAP Soluciones de Videovigilancia y Almacenamiento​Capacitación de QNAP Soluciones de Videovigilancia y Almacenamiento
​Capacitación de QNAP Soluciones de Videovigilancia y AlmacenamientoHernan Lopez
 
Human RIghts Conference in Geneva at UN- March 2011 invitation
Human RIghts Conference in Geneva at UN- March 2011 invitation Human RIghts Conference in Geneva at UN- March 2011 invitation
Human RIghts Conference in Geneva at UN- March 2011 invitation Unification Movement
 
Building Fodder Security in Rural Areas - Validation of Traditional Knowledge...
Building Fodder Security in Rural Areas - Validation of Traditional Knowledge...Building Fodder Security in Rural Areas - Validation of Traditional Knowledge...
Building Fodder Security in Rural Areas - Validation of Traditional Knowledge...copppldsecretariat
 
Manual de ferias
Manual de feriasManual de ferias
Manual de feriasDiego Bravo
 
Kertas kerja sempena lawatan bersama pandu puteri
Kertas kerja sempena lawatan bersama pandu puteriKertas kerja sempena lawatan bersama pandu puteri
Kertas kerja sempena lawatan bersama pandu puteriMastizah Gobik
 
Marketing concepts
Marketing conceptsMarketing concepts
Marketing conceptsYashank hm
 
La organización y funcionamiento del registro civil en vzu
La organización y funcionamiento del registro civil en vzuLa organización y funcionamiento del registro civil en vzu
La organización y funcionamiento del registro civil en vzuDarlin_12
 
Hurco 5 axis-brochure
Hurco 5 axis-brochureHurco 5 axis-brochure
Hurco 5 axis-brochureYasser Nour
 
"La creación de una marca: una necesidad para la Pyme"
"La creación de una marca: una necesidad para la Pyme""La creación de una marca: una necesidad para la Pyme"
"La creación de una marca: una necesidad para la Pyme"BrandSmith
 
Gafes rodrigo moreno rosales dn11
Gafes rodrigo moreno rosales dn11Gafes rodrigo moreno rosales dn11
Gafes rodrigo moreno rosales dn11Rodrigo Moreno
 
Emad Shoukry C.V 2016
Emad Shoukry C.V 2016Emad Shoukry C.V 2016
Emad Shoukry C.V 2016Emad Samaan
 

Andere mochten auch (20)

RoHS 2 como dar cumplimiento a los requisitos de la directiva
RoHS 2 como dar cumplimiento a los requisitos de la directivaRoHS 2 como dar cumplimiento a los requisitos de la directiva
RoHS 2 como dar cumplimiento a los requisitos de la directiva
 
11108131 王廷瑜
11108131 王廷瑜11108131 王廷瑜
11108131 王廷瑜
 
Érase una vez un reino llamado La Marca del mundo 2.0
Érase una vez un reino llamado La Marca del mundo 2.0Érase una vez un reino llamado La Marca del mundo 2.0
Érase una vez un reino llamado La Marca del mundo 2.0
 
Francisco Luiz
Francisco LuizFrancisco Luiz
Francisco Luiz
 
​Capacitación de QNAP Soluciones de Videovigilancia y Almacenamiento
​Capacitación de QNAP Soluciones de Videovigilancia y Almacenamiento​Capacitación de QNAP Soluciones de Videovigilancia y Almacenamiento
​Capacitación de QNAP Soluciones de Videovigilancia y Almacenamiento
 
Human RIghts Conference in Geneva at UN- March 2011 invitation
Human RIghts Conference in Geneva at UN- March 2011 invitation Human RIghts Conference in Geneva at UN- March 2011 invitation
Human RIghts Conference in Geneva at UN- March 2011 invitation
 
Building Fodder Security in Rural Areas - Validation of Traditional Knowledge...
Building Fodder Security in Rural Areas - Validation of Traditional Knowledge...Building Fodder Security in Rural Areas - Validation of Traditional Knowledge...
Building Fodder Security in Rural Areas - Validation of Traditional Knowledge...
 
Manual de ferias
Manual de feriasManual de ferias
Manual de ferias
 
Kertas kerja sempena lawatan bersama pandu puteri
Kertas kerja sempena lawatan bersama pandu puteriKertas kerja sempena lawatan bersama pandu puteri
Kertas kerja sempena lawatan bersama pandu puteri
 
Marketing concepts
Marketing conceptsMarketing concepts
Marketing concepts
 
La organización y funcionamiento del registro civil en vzu
La organización y funcionamiento del registro civil en vzuLa organización y funcionamiento del registro civil en vzu
La organización y funcionamiento del registro civil en vzu
 
Hurco 5 axis-brochure
Hurco 5 axis-brochureHurco 5 axis-brochure
Hurco 5 axis-brochure
 
Maria, Fuente De Espiritualidad Georgina Z
Maria, Fuente De Espiritualidad  Georgina ZMaria, Fuente De Espiritualidad  Georgina Z
Maria, Fuente De Espiritualidad Georgina Z
 
Coverma Unify
Coverma UnifyCoverma Unify
Coverma Unify
 
Sls t apd-es_o
Sls t apd-es_oSls t apd-es_o
Sls t apd-es_o
 
Casa Larco
Casa LarcoCasa Larco
Casa Larco
 
"La creación de una marca: una necesidad para la Pyme"
"La creación de una marca: una necesidad para la Pyme""La creación de una marca: una necesidad para la Pyme"
"La creación de una marca: una necesidad para la Pyme"
 
Gafes rodrigo moreno rosales dn11
Gafes rodrigo moreno rosales dn11Gafes rodrigo moreno rosales dn11
Gafes rodrigo moreno rosales dn11
 
Cat Sig Sauer
Cat Sig SauerCat Sig Sauer
Cat Sig Sauer
 
Emad Shoukry C.V 2016
Emad Shoukry C.V 2016Emad Shoukry C.V 2016
Emad Shoukry C.V 2016
 

Ähnlich wie ORM Doctrine

Ähnlich wie ORM Doctrine (20)

Doctrine2 sf2Vigo
Doctrine2 sf2VigoDoctrine2 sf2Vigo
Doctrine2 sf2Vigo
 
Creación de Builders y DSL's con Groovy
Creación de Builders y DSL's con GroovyCreación de Builders y DSL's con Groovy
Creación de Builders y DSL's con Groovy
 
Jquery parte 1
Jquery parte 1Jquery parte 1
Jquery parte 1
 
Introducción a Scala
Introducción a ScalaIntroducción a Scala
Introducción a Scala
 
Componentes, el arma secreta de Symfony2
Componentes, el arma secreta de Symfony2Componentes, el arma secreta de Symfony2
Componentes, el arma secreta de Symfony2
 
2 Introducción al lenguaje Ruby
2 Introducción al lenguaje Ruby2 Introducción al lenguaje Ruby
2 Introducción al lenguaje Ruby
 
Javascript Básico
Javascript BásicoJavascript Básico
Javascript Básico
 
Python boloñesa
Python boloñesa Python boloñesa
Python boloñesa
 
4 Introducción al lenguaje Scala
4 Introducción al lenguaje Scala4 Introducción al lenguaje Scala
4 Introducción al lenguaje Scala
 
Jruby On Rails. Ruby on Rails en la JVM
Jruby On Rails. Ruby on Rails en la JVMJruby On Rails. Ruby on Rails en la JVM
Jruby On Rails. Ruby on Rails en la JVM
 
Ruby para Java Developers
Ruby para Java DevelopersRuby para Java Developers
Ruby para Java Developers
 
Deployer PHP. Presentación para #PHPSevilla
Deployer PHP. Presentación para #PHPSevillaDeployer PHP. Presentación para #PHPSevilla
Deployer PHP. Presentación para #PHPSevilla
 
Introducción a Scala
Introducción a ScalaIntroducción a Scala
Introducción a Scala
 
32773 php-basico
32773 php-basico32773 php-basico
32773 php-basico
 
Javascript funcional
Javascript funcionalJavascript funcional
Javascript funcional
 
Clase 2
Clase 2 Clase 2
Clase 2
 
Ruby
RubyRuby
Ruby
 
IntroducciónPHP.pptx
IntroducciónPHP.pptxIntroducciónPHP.pptx
IntroducciónPHP.pptx
 
UTPL-PROGRAMACIÓN AVANZADA-II-BIMESTRE-(OCTUBRE 2011-FEBRERO 2012)
UTPL-PROGRAMACIÓN AVANZADA-II-BIMESTRE-(OCTUBRE 2011-FEBRERO 2012)UTPL-PROGRAMACIÓN AVANZADA-II-BIMESTRE-(OCTUBRE 2011-FEBRERO 2012)
UTPL-PROGRAMACIÓN AVANZADA-II-BIMESTRE-(OCTUBRE 2011-FEBRERO 2012)
 
Fundamento de poo en php
Fundamento de poo en phpFundamento de poo en php
Fundamento de poo en php
 

Mehr von Decharlas

Symfony 2 - decharlas 2010
Symfony 2 - decharlas 2010Symfony 2 - decharlas 2010
Symfony 2 - decharlas 2010Decharlas
 
Symfony: Domesticando las Vistas - decharlas
Symfony: Domesticando las Vistas - decharlasSymfony: Domesticando las Vistas - decharlas
Symfony: Domesticando las Vistas - decharlasDecharlas
 
Symfony: Domesticando los formularios
Symfony: Domesticando los formulariosSymfony: Domesticando los formularios
Symfony: Domesticando los formulariosDecharlas
 
Arquitectura y diseño de un entorno de desarrollo - decharlas
Arquitectura y diseño de un entorno de desarrollo - decharlasArquitectura y diseño de un entorno de desarrollo - decharlas
Arquitectura y diseño de un entorno de desarrollo - decharlasDecharlas
 
symfony admin generator - decharlas
symfony admin generator - decharlassymfony admin generator - decharlas
symfony admin generator - decharlasDecharlas
 
Symfony, cloud computing y webs scalables - decharlas
Symfony, cloud computing y webs scalables - decharlasSymfony, cloud computing y webs scalables - decharlas
Symfony, cloud computing y webs scalables - decharlasDecharlas
 
Caso práctico symfony: voota.es - decharlas
Caso práctico symfony: voota.es - decharlasCaso práctico symfony: voota.es - decharlas
Caso práctico symfony: voota.es - decharlasDecharlas
 
Caso práctico II: symfony en la gestión de un centro de computación avanzada ...
Caso práctico II: symfony en la gestión de un centro de computación avanzada ...Caso práctico II: symfony en la gestión de un centro de computación avanzada ...
Caso práctico II: symfony en la gestión de un centro de computación avanzada ...Decharlas
 
Introducción a symfony - decharlas
Introducción a symfony - decharlasIntroducción a symfony - decharlas
Introducción a symfony - decharlasDecharlas
 
Symfony plugins - decharlas
Symfony plugins - decharlasSymfony plugins - decharlas
Symfony plugins - decharlasDecharlas
 

Mehr von Decharlas (10)

Symfony 2 - decharlas 2010
Symfony 2 - decharlas 2010Symfony 2 - decharlas 2010
Symfony 2 - decharlas 2010
 
Symfony: Domesticando las Vistas - decharlas
Symfony: Domesticando las Vistas - decharlasSymfony: Domesticando las Vistas - decharlas
Symfony: Domesticando las Vistas - decharlas
 
Symfony: Domesticando los formularios
Symfony: Domesticando los formulariosSymfony: Domesticando los formularios
Symfony: Domesticando los formularios
 
Arquitectura y diseño de un entorno de desarrollo - decharlas
Arquitectura y diseño de un entorno de desarrollo - decharlasArquitectura y diseño de un entorno de desarrollo - decharlas
Arquitectura y diseño de un entorno de desarrollo - decharlas
 
symfony admin generator - decharlas
symfony admin generator - decharlassymfony admin generator - decharlas
symfony admin generator - decharlas
 
Symfony, cloud computing y webs scalables - decharlas
Symfony, cloud computing y webs scalables - decharlasSymfony, cloud computing y webs scalables - decharlas
Symfony, cloud computing y webs scalables - decharlas
 
Caso práctico symfony: voota.es - decharlas
Caso práctico symfony: voota.es - decharlasCaso práctico symfony: voota.es - decharlas
Caso práctico symfony: voota.es - decharlas
 
Caso práctico II: symfony en la gestión de un centro de computación avanzada ...
Caso práctico II: symfony en la gestión de un centro de computación avanzada ...Caso práctico II: symfony en la gestión de un centro de computación avanzada ...
Caso práctico II: symfony en la gestión de un centro de computación avanzada ...
 
Introducción a symfony - decharlas
Introducción a symfony - decharlasIntroducción a symfony - decharlas
Introducción a symfony - decharlas
 
Symfony plugins - decharlas
Symfony plugins - decharlasSymfony plugins - decharlas
Symfony plugins - decharlas
 

Kürzlich hochgeladen

Actividades de computación para alumnos de preescolar
Actividades de computación para alumnos de preescolarActividades de computación para alumnos de preescolar
Actividades de computación para alumnos de preescolar24roberto21
 
David_Gallegos - tarea de la sesión 11.pptx
David_Gallegos - tarea de la sesión 11.pptxDavid_Gallegos - tarea de la sesión 11.pptx
David_Gallegos - tarea de la sesión 11.pptxDAVIDROBERTOGALLEGOS
 
La Electricidad Y La Electrónica Trabajo Tecnología.pdf
La Electricidad Y La Electrónica Trabajo Tecnología.pdfLa Electricidad Y La Electrónica Trabajo Tecnología.pdf
La Electricidad Y La Electrónica Trabajo Tecnología.pdfjeondanny1997
 
_Planificacion Anual NTICX 2024.SEC.21.4.1.docx.pdf
_Planificacion Anual NTICX 2024.SEC.21.4.1.docx.pdf_Planificacion Anual NTICX 2024.SEC.21.4.1.docx.pdf
_Planificacion Anual NTICX 2024.SEC.21.4.1.docx.pdfBetianaJuarez1
 
Herramientas que posibilitan la información y la investigación.pdf
Herramientas que posibilitan la información y la investigación.pdfHerramientas que posibilitan la información y la investigación.pdf
Herramientas que posibilitan la información y la investigación.pdfKarinaCambero3
 
Trabajo de tecnología excel avanzado.pdf
Trabajo de tecnología excel avanzado.pdfTrabajo de tecnología excel avanzado.pdf
Trabajo de tecnología excel avanzado.pdfedepmariaperez
 
Trabajando con Formasy Smart art en power Point
Trabajando con Formasy Smart art en power PointTrabajando con Formasy Smart art en power Point
Trabajando con Formasy Smart art en power PointValerioIvanDePazLoja
 
Análisis de los artefactos (nintendo NES)
Análisis de los artefactos (nintendo NES)Análisis de los artefactos (nintendo NES)
Análisis de los artefactos (nintendo NES)JuanStevenTrujilloCh
 
Documentacion Electrónica en Actos Juridicos
Documentacion Electrónica en Actos JuridicosDocumentacion Electrónica en Actos Juridicos
Documentacion Electrónica en Actos JuridicosAlbanyMartinez7
 
Análisis de Artefactos Tecnologicos (3) (1).pdf
Análisis de Artefactos Tecnologicos  (3) (1).pdfAnálisis de Artefactos Tecnologicos  (3) (1).pdf
Análisis de Artefactos Tecnologicos (3) (1).pdfsharitcalderon04
 
La electricidad y la electronica.10-7.pdf
La electricidad y la electronica.10-7.pdfLa electricidad y la electronica.10-7.pdf
La electricidad y la electronica.10-7.pdfcristianrb0324
 
LUXOMETRO EN SALUD OCUPACIONAL(FINAL).ppt
LUXOMETRO EN SALUD OCUPACIONAL(FINAL).pptLUXOMETRO EN SALUD OCUPACIONAL(FINAL).ppt
LUXOMETRO EN SALUD OCUPACIONAL(FINAL).pptchaverriemily794
 
La tecnología y su impacto en la sociedad
La tecnología y su impacto en la sociedadLa tecnología y su impacto en la sociedad
La tecnología y su impacto en la sociedadEduardoSantiagoSegov
 
Inteligencia Artificial. Matheo Hernandez Serrano USCO 2024
Inteligencia Artificial. Matheo Hernandez Serrano USCO 2024Inteligencia Artificial. Matheo Hernandez Serrano USCO 2024
Inteligencia Artificial. Matheo Hernandez Serrano USCO 2024u20211198540
 
Agencia Marketing Branding Google Workspace Deployment Services Credential Fe...
Agencia Marketing Branding Google Workspace Deployment Services Credential Fe...Agencia Marketing Branding Google Workspace Deployment Services Credential Fe...
Agencia Marketing Branding Google Workspace Deployment Services Credential Fe...Marketing BRANDING
 
Viguetas Pretensadas en concreto armado
Viguetas Pretensadas  en concreto armadoViguetas Pretensadas  en concreto armado
Viguetas Pretensadas en concreto armadob7fwtwtfxf
 
LINEA DE TIEMPO LITERATURA DIFERENCIADO LITERATURA.pptx
LINEA DE TIEMPO LITERATURA DIFERENCIADO LITERATURA.pptxLINEA DE TIEMPO LITERATURA DIFERENCIADO LITERATURA.pptx
LINEA DE TIEMPO LITERATURA DIFERENCIADO LITERATURA.pptxkimontey
 
#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx
#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx
#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptxHugoGutierrez99
 
LAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptx
LAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptxLAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptx
LAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptxAlexander López
 

Kürzlich hochgeladen (20)

Actividades de computación para alumnos de preescolar
Actividades de computación para alumnos de preescolarActividades de computación para alumnos de preescolar
Actividades de computación para alumnos de preescolar
 
David_Gallegos - tarea de la sesión 11.pptx
David_Gallegos - tarea de la sesión 11.pptxDavid_Gallegos - tarea de la sesión 11.pptx
David_Gallegos - tarea de la sesión 11.pptx
 
La Electricidad Y La Electrónica Trabajo Tecnología.pdf
La Electricidad Y La Electrónica Trabajo Tecnología.pdfLa Electricidad Y La Electrónica Trabajo Tecnología.pdf
La Electricidad Y La Electrónica Trabajo Tecnología.pdf
 
_Planificacion Anual NTICX 2024.SEC.21.4.1.docx.pdf
_Planificacion Anual NTICX 2024.SEC.21.4.1.docx.pdf_Planificacion Anual NTICX 2024.SEC.21.4.1.docx.pdf
_Planificacion Anual NTICX 2024.SEC.21.4.1.docx.pdf
 
Herramientas que posibilitan la información y la investigación.pdf
Herramientas que posibilitan la información y la investigación.pdfHerramientas que posibilitan la información y la investigación.pdf
Herramientas que posibilitan la información y la investigación.pdf
 
Trabajo de tecnología excel avanzado.pdf
Trabajo de tecnología excel avanzado.pdfTrabajo de tecnología excel avanzado.pdf
Trabajo de tecnología excel avanzado.pdf
 
Trabajando con Formasy Smart art en power Point
Trabajando con Formasy Smart art en power PointTrabajando con Formasy Smart art en power Point
Trabajando con Formasy Smart art en power Point
 
Análisis de los artefactos (nintendo NES)
Análisis de los artefactos (nintendo NES)Análisis de los artefactos (nintendo NES)
Análisis de los artefactos (nintendo NES)
 
Documentacion Electrónica en Actos Juridicos
Documentacion Electrónica en Actos JuridicosDocumentacion Electrónica en Actos Juridicos
Documentacion Electrónica en Actos Juridicos
 
Análisis de Artefactos Tecnologicos (3) (1).pdf
Análisis de Artefactos Tecnologicos  (3) (1).pdfAnálisis de Artefactos Tecnologicos  (3) (1).pdf
Análisis de Artefactos Tecnologicos (3) (1).pdf
 
La electricidad y la electronica.10-7.pdf
La electricidad y la electronica.10-7.pdfLa electricidad y la electronica.10-7.pdf
La electricidad y la electronica.10-7.pdf
 
LUXOMETRO EN SALUD OCUPACIONAL(FINAL).ppt
LUXOMETRO EN SALUD OCUPACIONAL(FINAL).pptLUXOMETRO EN SALUD OCUPACIONAL(FINAL).ppt
LUXOMETRO EN SALUD OCUPACIONAL(FINAL).ppt
 
La tecnología y su impacto en la sociedad
La tecnología y su impacto en la sociedadLa tecnología y su impacto en la sociedad
La tecnología y su impacto en la sociedad
 
Inteligencia Artificial. Matheo Hernandez Serrano USCO 2024
Inteligencia Artificial. Matheo Hernandez Serrano USCO 2024Inteligencia Artificial. Matheo Hernandez Serrano USCO 2024
Inteligencia Artificial. Matheo Hernandez Serrano USCO 2024
 
Agencia Marketing Branding Google Workspace Deployment Services Credential Fe...
Agencia Marketing Branding Google Workspace Deployment Services Credential Fe...Agencia Marketing Branding Google Workspace Deployment Services Credential Fe...
Agencia Marketing Branding Google Workspace Deployment Services Credential Fe...
 
Viguetas Pretensadas en concreto armado
Viguetas Pretensadas  en concreto armadoViguetas Pretensadas  en concreto armado
Viguetas Pretensadas en concreto armado
 
LINEA DE TIEMPO LITERATURA DIFERENCIADO LITERATURA.pptx
LINEA DE TIEMPO LITERATURA DIFERENCIADO LITERATURA.pptxLINEA DE TIEMPO LITERATURA DIFERENCIADO LITERATURA.pptx
LINEA DE TIEMPO LITERATURA DIFERENCIADO LITERATURA.pptx
 
#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx
#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx
#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx
 
El camino a convertirse en Microsoft MVP
El camino a convertirse en Microsoft MVPEl camino a convertirse en Microsoft MVP
El camino a convertirse en Microsoft MVP
 
LAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptx
LAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptxLAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptx
LAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptx
 

ORM Doctrine

  • 1. Jornadas Symfony 5 y 6 de julio 2010 Universitat Jaume I, Castellón http://decharlas.uji.es/symfony organizan patrocinan colaboran
  • 2. Doctrine Nacho Martín 5 y 6 de julio 2010 Jornadas Symfony Universitat Jaume I, Castellón http://decharlas.uji.es/symfony
  • 3. ¿Qué es Doctrine? ● Object Relational Mapper hecho para PHP >=5.2.3 (Doctrine 2.0 PHP >5.3) ● Basado en Hibernate (Java) ● ¿Y Propel? Jornadas Symfony http://decharlas.uji.es/symfony
  • 4. Componentes Jornadas Symfony http://decharlas.uji.es/symfony
  • 5. Activación //config/ProjectConfiguration.class.php public function setup() { $this->enablePlugins(array('sfDoctrinePlugin')); $this->disablePlugins(array('sfPropelPlugin')); } #config/databases.yml all: doctrine: class: sfDoctrineDatabase param: dsn: 'mysql:host=localhost;dbname=midb' username: usuario password: secreto Jornadas Symfony http://decharlas.uji.es/symfony
  • 6. Una aplicación de ejemplo ● Lista ToDo ● Con items (one-many) ● Y tags (many-many) Jornadas Symfony http://decharlas.uji.es/symfony
  • 7. El esquema YAML Todo: actAs: Timestampable: ~ columns: name: { type: string(255), notnull: true} description: { type: string(1024) } relations: Tags: { class: Tag, refClass: TodoTag, local: todo_id, foreign: tag_id, foreignAlias: Todos} Item: actAs: Timestampable: ~ columns: name: { type: string(255) } text: { type: string(4000) } todo_id: { type: integer, notnull: true } relations: Todo: { class: Todo, onDelete: CASCADE, local: todo_id, foreign: id, foreignAlias: items } TodoTag: columns: tag_id: { type: integer, primary: true } todo_id: { type: integer, primary: true } relations: Tag: { onDelete: CASCADE, local: tag_id, foreign: id } Todo: { onDelete: CASCADE, local: todo_id, foreign: id } Tag: columns: name: { type: string(255) } Jornadas Symfony http://decharlas.uji.es/symfony
  • 8. El modelo (columnas) abstract class BaseTodo extends sfDoctrineRecord { public function setTableDefinition() { $this->setTableName('todo'); $this->hasColumn('name', 'string', 255, array( 'type' => 'string', 'notnull' => true, 'length' => '255', )); $this->hasColumn('description', 'string', 1024, array( 'type' => 'string', 'length' => '1024', )); } Jornadas Symfony http://decharlas.uji.es/symfony
  • 9. El modelo (relaciones) public function setUp() { parent::setUp(); $this->hasMany('Tag as Tags', array( 'refClass' => 'TodoTag', 'local' => 'todo_id', 'foreign' => 'tag_id')); $this->hasMany('Item as items', array( 'local' => 'id', 'foreign' => 'todo_id')); $this->hasMany('TodoTag', array( 'local' => 'id', 'foreign' => 'tag_id')); //Behaviour $timestampable0 = new Doctrine_Template_Timestampable(); $this->actAs($timestampable0); } } Jornadas Symfony http://decharlas.uji.es/symfony
  • 10. Fixtures (Doctrine 1) Todo: denver: name: Cosas que hacer en Denver description: Cuando hayamos muerto Item: gambas: name: Comer gambas Todo: denver gangsters: name: Cosas de gangsters Todo: denver Tag: turismo: name: Turismo gangsteril Todos: [denver] Jornadas Symfony http://decharlas.uji.es/symfony
  • 11. DQL ● Simplifica SQL y es portable ● Incorpora POO a SQL Jornadas Symfony http://decharlas.uji.es/symfony
  • 12. DQL $q = Doctrine_Query::create() ->select('l.*, i.name, t.name') ->from('Todo l') ->innerJoin('l.Items i') ->leftJoin('l.Tags t'); echo $q->getSqlQuery(); SELECT t.id AS t__id, t.name AS t__name, t.description AS t__description, t.created_at AS t__created_at, t.updated_at AS t__updated_at, i.id AS i__id, i.name AS i__name, t2.id AS t2__id, t2.name AS t2__name FROM todo t INNER JOIN item i ON t.id = i.todo_id LEFT JOIN todo_tag t3 ON (t.id = t3.todo_id) LEFT JOIN tag t2 ON t2.id = t3.tag_id Jornadas Symfony http://decharlas.uji.es/symfony
  • 13. Objetos Métodos de acceso y manipulación $list = new Todo(); //Manipulación 1 $list->name = "Cosas que hacer en Denver"; 2 $list['name'] = "Cosas que hacer en Denver"; 3 $list->set('name', "Cosas que hacer en Denver"); //Acceso 1 echo $list->name; 2 echo $list['name']; //Recomendado (hidratación) 3 echo $list->get('name'); Jornadas Symfony http://decharlas.uji.es/symfony
  • 14. Hidratación (I) ● En objetos ● En arrays (más rápido) ● Scalar ● Single Scalar ● Bajo demanda ● … ¿No es suficiente? ¡Escribe el tuyo! Jornadas Symfony http://decharlas.uji.es/symfony
  • 15. Hidratación (II) $q = Doctrine_Query::create() ->from('Todo l') ->innerJoin('l.Items i'); $lists = $q->execute(); //Record echo $lists[0]['name']; Jornadas Symfony http://decharlas.uji.es/symfony
  • 16. Hidratación (II) Array $q = Doctrine_Query::create() ( ->from('Todo l') [0] => Array ( ->innerJoin('l.Items i'); [id] => 1 [name] => Cosas que hacer en Denver $lists = $q->execute(); //Record [description] => Cuando hayamos muerto echo $lists[0]['name']; [created_at] => 2010-06-22 23:55:02 [updated_at] => 2010-06-22 23:55:02 [Items] => Array $lists = $q->fetchArray(); //Array ( echo $lists[0]['name']; [0] => Array //O bien $q->execute(array(), ( Doctrine::HYDRATE_ARRAY); [id] => 1 [name] => Comer gambas print_r($lists); [text] => [todo_id] => 1 [created_at] => 2010-06-22 23:55:02 [updated_at] => 2010-06-22 23:55:02 ) [1] => Array (…) ) ) ) Jornadas Symfony http://decharlas.uji.es/symfony
  • 17. Hidratación (III) ● El acceso por arrays funciona en los dos métodos de hidratación ● La hidratación por arrays es más eficiente si solo queremos consultar datos directos de la BD ● fetchArray() es un alias de execute() con la hidratación por array ● Uso de foreach, count(), isset(), unset() Jornadas Symfony http://decharlas.uji.es/symfony
  • 18. Definiendo setters/getters class Todo extends BaseTodo { //Nuevo getter public function getDescriptionHtml() { return Markdown::parse(htmlspecialchars( $this->description)); } //Sobrecarga del setter public function setDescription($description) { return $this->_set('description', Markdown::parse(htmlspecialchars($description))); } } Jornadas Symfony http://decharlas.uji.es/symfony
  • 19. Relaciones $list = new Todo(); $list['name'] = "Libros para este verano"; $list->Items[]->name = "Hablemos de Langostas"; $list->save(); //Usando link() ● Las relaciones son $item = new Item(); intuitivas $item['name'] = "La broma infinita"; $item->link('Todo',array($list['id'])); ● Siempre podemos recurrir $item->save(); a DQL //Borrar $list->Items[0]->delete(); ● Pero en DQL no se //Siempre nos quedará DQL ejecutarán preDelete(), $q = Doctrine_Query::create() postDelete()... (!) ->delete('Item') ->addWhere('todo_id = ?', $list['id']) ->whereIn('name', array($item['name'], 'otro nombre')); $q->execute(); Jornadas Symfony http://decharlas.uji.es/symfony
  • 20. Many to many Array $q = Doctrine_Query::create() ( [0] => Array ->from('Todo l') ( ->leftJoin('l.TodoTag tt') [id] => 27 ->leftJoin('tt.Tag t'); [name] => Cosas que hacer en Denver print_r($q->fetchArray()); [description] => Cuando hayamos muerto [created_at] => 2010-06-23 20:35:41 //Equivalente [updated_at] => 2010-06-23 20:35:41 $q = Doctrine_Query::create() [TodoTag] => Array ->from('Todo l') ( ->leftJoin('l.Tags t'); [0] => Array print_r($q->fetchArray()); ( [tag_id] => 2 [todo_id] => 27 ● Podemos “olvidarnos” [Tag] => Array ( de la tabla intermedia [id] => 2 [name] => Turismo ) ) ) ) ) Jornadas Symfony http://decharlas.uji.es/symfony
  • 21. Mucha tela que cortar ● Behaviours ● Validadores ● Migraciones ● Herencia ● Caché ● Event listeners ● … Jornadas Symfony http://decharlas.uji.es/symfony
  • 22. Mucha tela que cortar ● Behaviours ● Validadores ● Migraciones ● Herencia ● Caché ● Event listeners ● … ¿Pero y Doctrine2? Veamos Doctrine2 Jornadas Symfony http://decharlas.uji.es/symfony
  • 23. Doctrine2 ● Reescritura completa del código para PHP 5.3 ● Mejoras importantes de rendimiento ● Menos magia ● Caché mejorada ● Entidades Jornadas Symfony http://decharlas.uji.es/symfony
  • 24. Entidades (I) <?php namespace Entities; /** @Entity @Table(name="usuarios") */ class Usuario { /** * @Id @Column(type="integer") * @GeneratedValue(strategy="AUTO") */ private $id; /** @Column(type="string", length=50) */ private $nombre; /** * @OneToOne(targetEntity="Direccion") * @JoinColumn(name="direccion_id", referencedColumnName="id") */ private $direccion; DocBlock Annotations Jornadas Symfony http://decharlas.uji.es/symfony
  • 25. Entidades (II) public function getId() { return $this->id; } public function getNombre() { return $this->nombre; } public function setNombre($nombre) { $this->nombre = $nombre; } public function getDireccion() { return $this->direccion; } public function setDireccion(Direccion $direccion) { if ($this->direccion !== $direccion) { $this->direccion = $direccion; $direccion->setUsuario($this); } } } Jornadas Symfony http://decharlas.uji.es/symfony
  • 26. Entidades (III) ● No descienden de ninguna clase, están “separadas” del ORM, aunque mapeadas por él ● Menos magia. Es más fácil entender qué está pasando ● Más rápidas ● Herencia ● Gestionadas por el Entity Manager ● Sí, se pueden escribir en YAML y XML ;) Jornadas Symfony http://decharlas.uji.es/symfony
  • 27. Fixtures $em = $this->getEntityManager(); $user1 = new ModelsUsuario(); $user1->nombre = 'Nacho'; ● Adiós al YAML. Se escriben en PHP ● ¿Por qué? ● Es más rápido cargarlas ● El código para tratar fixtures en YAML introdujo muchos bugs en el pasado Jornadas Symfony http://decharlas.uji.es/symfony
  • 28. persist() y flush() $user = new EntitiesUsuario; $user->setNombre('Nacho'); $entitymanager->persist($user); $entitymanager->flush(); ● Atención al uso de espacios de nombre ● Persist “marca” el objeto para guardar ● Flush ejecuta la unidad de trabajo Jornadas Symfony http://decharlas.uji.es/symfony
  • 29. Rendimiento (I) for ($i=0; $i<1000; $i++){ $user = new EntitiesUsuario; $user->setNombre('Nacho'); $em->persist($user); } $inicio = microtime(true); $em->flush(); $final = microtime(true); echo $final-$inicio."n"; 0.377s ////////////////////////// $inicio = microtime(true); for ($i=0; $i<1000; $i++){ mysql_query("INSERT INTO usuarios (nombre) VALUES ('Nacho')", $link); } 41.4s $final = microtime(true); echo $final-$inicio."n"; Jornadas Symfony http://decharlas.uji.es/symfony
  • 30. Rendimiento (II) ● Doctrine2 gestiona las transacciones por nosotros ● Así que es más rápido que código PHP+SQL mal optimizado ● (Por supuesto usar transacciones en PHP+SQL es más rápido que Doctrine2) ● También podemos controlar las transacciones nosotros Jornadas Symfony http://decharlas.uji.es/symfony
  • 31. Eventos Lifecycle ● pre/postRemove ● pre/postPersist ● pre/postUpdate ● postLoad : carga desde BD ● loadClassMetadata : carga desde metadatos (annotations, yaml, xml) ● onFlush /** @Entity @HasLifecycleCallbacks */ class Usuario { //(...) /** @PostPersist */ public function doAlgoOnPostPersist() { $this->nombre = 'Me han cambiado en el postpersist'; } Jornadas Symfony http://decharlas.uji.es/symfony
  • 32. Behaviours (I) En Doctrine2 son código normal de PHP que extiende la funcionalidad base de las entidades /** @HasLifecycleCallbacks */ class BlogPost { //(...) public function __construct() { $this->created = $this->updated = new DateTime("now"); } /** * @PreUpdate */ public function updated() { $this->updated = new DateTime("now"); } } Jornadas Symfony http://decharlas.uji.es/symfony
  • 33. Behaviours (II) ¿Pero cómo hacer el código reutilizable entre entidades? Usando interfaces, eventos y código PHP orientado a objetos Ejemplos: http://github.com/guilhermeblanco/Doctrine2-Sluggable-Functional-Behavior http://github.com/guilhermeblanco/Doctrine2-Hierarchical-Structural-Behavior http://www.doctrine-project.org/blog/doctrine2-versionable Jornadas Symfony http://decharlas.uji.es/symfony
  • 34. Migraciones (I) Hacen el esquema versionable BD (antes) BD (después) Esquema Fichero de migración Jornadas Symfony http://decharlas.uji.es/symfony
  • 35. Migraciones (I) Hacen el esquema versionable BD (antes) BD (después) Comparar Esquema Fichero de migración Jornadas Symfony http://decharlas.uji.es/symfony
  • 36. Migraciones (I) Hacen el esquema versionable BD (antes) BD (después) Comparar Generar Esquema Fichero de migración Jornadas Symfony http://decharlas.uji.es/symfony
  • 37. Migraciones (I) Hacen el esquema versionable BD (antes) BD (después) Comparar Generar Esquema Fichero de migración Jornadas Symfony http://decharlas.uji.es/symfony
  • 38. Migraciones (I) Hacen el esquema versionable Migrar BD (antes) BD (después) Comparar Generar Esquema Fichero de migración Jornadas Symfony http://decharlas.uji.es/symfony
  • 39. Migraciones (II) Aspecto de un fichero de migración class Version20100416130401 extends AbstractMigration { public function up(Schema $schema) { $table = $schema->createTable('users'); $table->addColumn('username', 'string'); $table->addColumn('password', 'string'); } public function down(Schema $schema) { $schema->dropTable('users'); } } Jornadas Symfony http://decharlas.uji.es/symfony
  • 40. Migraciones (III) Gestionadas desde la consola: ● Diff: tras cambiar una entidad, genera la migración necesaria para cambiar la BD ● Dry-run: muestra el SQL para cerciorarnos de que es lo que esperamos ● Status: muestra en qué estado (versión, migraciones posibles, fecha...) estamos ● Migrate: ejecuta la migración (hacia adelante o hacia atrás → revertir) ● Write-sql: en lugar de migrar, escribe el SQL a un fichero Jornadas Symfony http://decharlas.uji.es/symfony
  • 41. MongoDB (ODM) ● El ODM tiene el mismo aspecto que el ORM (métodos parecidos, Entidad → Documento, EntityManager → DocumentManager,...) ● Mañana hay una charla sobre MongoDB y Symfony ;) Jornadas Symfony http://decharlas.uji.es/symfony
  • 42. ¿Preguntas? Si surgen más tarde ;) : nitram.ohcan@gmail.com twitter:@nacmartin http://nacho-martin.com Jornadas Symfony http://decharlas.uji.es/symfony