Symfony2 and Doctrine2 Integration
Upcoming SlideShare
Loading in...5
×
 

Symfony2 and Doctrine2 Integration

on

  • 31,259 views

 

Statistics

Views

Total Views
31,259
Views on SlideShare
27,984
Embed Views
3,275

Actions

Likes
33
Downloads
512
Comments
2

32 Embeds 3,275

http://d.hatena.ne.jp 829
http://www.symfony.es 575
http://www.symfony-project.org 536
http://romain.cambien.net 501
http://symfony.com 327
http://www.symfonylab.com 121
http://swik.net 116
http://www.symfony.gr.jp 102
http://www.sfexception.com 75
http://rcambien.tumblr.com 16
http://coderwall.com 10
http://www.pearltrees.com 9
http://static.slidesharecdn.com 7
http://translate.googleusercontent.com 7
http://rimzy.net 6
http://www.prestataire-symfony.com 5
http://webcache.googleusercontent.com 5
http://symfony.lab216.com 4
http://www.phpframeworks.com 3
http://feeds.feedburner.com 3
https://twitter.com 3
http://www.slideshare.net 3
https://twimg0-a.akamaihd.net 2
resource://brief-content 2
http://health.medicbd.com 1
http://127.0.0.1:8795 1
https://klti.de 1
http://www.taaza.com 1
http://twitter.com 1
https://si0.twimg.com 1
http://localhost 1
http://www.health.medicbd.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Symfony2 and Doctrine2 Integration Symfony2 and Doctrine2 Integration Presentation Transcript

  • Symfony and Doctrine What’s new in the Symfony and Doctrine Integration Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Updated DoctrineBundle • Doctrine2 features fully integrated – Database Abstraction Layer – Object Relational Mapper Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • DoctrineMongoDBBundle • MongoDB Object Document Mapper – Transparent persistence to MongoDB – Same architecture as ORM – Map a class as an entity and document Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • DoctrineMigrationsBundle • Integration with the database migrations project. • Easily manage and deploy different versions of your database. • Generate migrations when you change your schema mapping information Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • DBAL • To use just the DBAL you must configure it: doctrine.dbal: dbname: Symfony user: root password: ~ Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • DBAL • If you need to specify multiple connections you can use the following syntax: doctrine.dbal: default_connection: default connections: default: driver: PDOSqlite dbname: Symfony user: root password: null host: localhost port: ~ path: %kernel.data_dir%/symfony.sqlite event_manager_class: DoctrineCommonEventManager configuration_class: DoctrineDBALConfiguration wrapper_class: ~ options: [] Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • DBAL Console Commands • Create all configured databases $ php console doctrine:database:create • Create a specific database $ php console doctrine:database:create --connection=default • Drop all configured databases $ php console doctrine:database:drop • Drop a specific database $ php console doctrine:database:drop --connection=default Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • DBAL Console Commands • Execute SQL queries $ php console doctrine:query:sql “SELECT * FROM user” • Specify connection $ php console doctrine:query:sql “...” --connection=default Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • DBAL • Get the default configured database connection: class MyController extends DoctrineController { public function indexAction() { $conn = $this->getDatabaseConnection(); // ... } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • DBAL • Get a configured database connection service by its name: class MyController extends DoctrineController { public function indexAction() { $conn = $this->getDatabaseConnection('default'); // ... } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • ORM • The EntityManager • Central place for persisting and retrieving entities • Multiple instances allowed • One EntityManager per database connection $config = new DoctrineORMConfiguration(); $config->setMetadataCacheImpl(new DoctrineCommonCacheArrayCache); $driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities")); $config->setMetadataDriverImpl($driverImpl); $config->setProxyDir(__DIR__ . '/Proxies'); $config->setProxyNamespace('Proxies'); $connectionOptions = array( 'driver' => 'pdo_sqlite', 'path' => 'database.sqlite' ); $em = DoctrineORMEntityManager::create($connectionOptions, $config); • Dependency Injection handles the creation and management of entity manager services Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • ORM • What is an Entity? It is a regular PHP object that has been mapped to the Doctrine2 ORM: /** @Entity */ class User { /** * @Id @Column(type="integer") * @GeneratedValue */ private $id; /** @Column(type="string", length=255) */ private $name; public function getId() { return $this->id; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • ORM • No more magic in your domain • Clean and testable • Fast! • Only limited by what you can do with PHP OO to design your domain • Inheritance • Use __construct() without any problems • Entities are persisted transparently by the EntityManager Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • ORM • Configure an entity manager to start using the ORM: doctrine.orm: default_entity_manager: default cache_driver: apc # array, apc, memcache, xcache entity_managers: default: connection: default Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • ORM • Console commands implemented for improved developer workflow: Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • ORM • Console commands implemented for improved developer workflow: • Ensure production settings • Clear metadata, query and result cache • Load data fixtures • Create and drop configured databases • Generate entities from mapping information • Generate new skeleton entities • Generate skeleton entity repository classes • Convert mapping information between formats • Convert a Doctrine1 schema • Import mapping information from an existing database • Execute DQL and SQL queries • Create, drop and update database schema from mapping information Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • ORM • Get the default configured entity manager service: class MyController extends DoctrineController { public function indexAction() { $em = $this->getEntityManager(); // ... } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • ORM • Get a configured entity manager service by its name: class MyController extends DoctrineController { public function indexAction() { $em = $this->getEntityManager('default'); // ... } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • ORM • Persisting entities is as simple as creating the object and telling Doctrine to persist it: class MyController extends DoctrineController { public function createAction() { $em = $this->getEntityManager(); $user = new User(); $user->setName('Jonathan H. Wage'); $em->persist($user); $em->flush(); // ... } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • ORM • Creating Query instances and issue DQL queries to retrieve objects: class MyController extends DoctrineController { public function indexAction() { $em = $this->getEntityManager(); $query = $em->createQuery('select u from MyBundle:User u'); $users = $query->execute(); // ... } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • ORM • Creating QueryBuilder instances to programatically build DQL queries through a fluent interface: class MyController extends DoctrineController { public function indexAction() { $em = $this->getEntityManager(); $qb = $em->createQueryBuilder() ->select('u') ->from('MyBundle:User', 'u'); $query = $qb->getQuery(); $users = $query->execute(); // ... } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • ORM • Update your database schema during development as your domain model evolves • Add a new column to our User entity /** @Entity */ class User { // ... /** @Column(type="string", length=255) */ private $email; } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • ORM • Run update command to update your database schema from mapping information $ php console doctrine:schema:update • The above compares your current database schema to your new mapping information and executes the necessary queries to bring your database up-to-date. Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Object Document Mapper • New Doctrine Project for persisting objects to MongoDB • Same architecture as ORM • Transparently persist PHP5 objects to MongoDB Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • The DocumentManager • Central place for persisting and retrieving documents • Multiple instances allowed $config = new Configuration(); $config->setProxyDir(__DIR__ . '/Proxies'); $config->setProxyNamespace('Proxies'); $config->setDefaultDB('doctrine_odm_sandbox'); $reader = new AnnotationReader(); $reader->setDefaultAnnotationNamespace('DoctrineODMMongoDBMapping'); $config->setMetadataDriverImpl(new AnnotationDriver($reader, __DIR__ . '/Documents')); $dm = DocumentManager::create(new Mongo(), $config); • Dependency Injection handles the creation and management of document manager services Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • To use the MongoDB ODM you must configure it: doctrine_odm.mongodb: default_document_manager: default cache_driver: array document_managers: default: connection: mongodb connections: mongodb: server: localhost/somedatabase Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • If the defaults are good enough for you then you can omit all the previous options: doctrine_odm.mongodb: ~ Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • What is a Document? It is a regular PHP object that has been mapped to the MongoDB ODM: /** @Document */ class User { /** * @Id */ private $id; /** @String */ private $name; public function getId() { return $this->id; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Get the default configured document manager: class MyController extends DoctrineController { public function indexAction() { $dm = $this->getDocumentManager(); // ... } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Get a configured document manager by its name: class MyController extends DoctrineController { public function indexAction() { $dm = $this->getDocumentManager('default'); // ... } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Just like the ORM persisting documents is easy: class MyController extends DoctrineController { public function createAction() { $dm = $this->getDocumentManager(); $user = new User(); $user->setName('Jonathan H. Wage'); $dm->persist($user); $dm->flush(); // ... } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Change tracking – All objects are tracked in an identity map – Changesets are calculated on flush – Changesets are used to perform updates using the atomic operators • The following code results in an efficient mongo update with only the properties that need updated: Array ( $user->setName('new name'); -> [$set] => Array ( $dm->flush(); [name] => new name ) ) Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Traditional MongoDB find() and findOne() $users = $dm->find('User', $criteria); $query = $dm->findOne('User', array('username' => 'jwage') ); $user = $query->getSingleResult(); Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Query API for building MongoDB queries through a fluent OO interface: class MyController extends DoctrineController { public function indexAction() { $dm = $this->getDocumentManager(); $query = $dm->createQuery('MyBundle:User'); $users = $query->execute(); // ... } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Using Query builder API class MyController extends DoctrineController { public function indexAction() { $dm = $this->getDocumentManager(); $query = $dm->createQuery('User') ->where('username', 'jwage'); $user = $query->getSingleResult(); // ... } } • where(), whereIn(), whereMod(), whereNot(), etc. Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Fluent Query interface generates and executes find() and findOne() methods internally • Query information is collected via fluent oo interface and executed later Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Document Query Language (DQL) – SQL like grammar for querying MongoDB • Query types supported – Find – Insert – Update – Remove Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Find query $query = $dm->query('find all User'); $users = $query->execute(); Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Selecting fields $query = $dm->query('find username, password User'); Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • $slice operator for paging embedded collections $query = $dm->query('find comments skip 20 limit 10 Post'); Array ( [comments] => Array ( [$slice] => Array ( [0] => 20 [1] => 10 ) ) ) Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Use atomic operators $query = $dm->query("update User set password = 'changeme' where username = 'jwage'"); Array ( [$set] => Array ( [password] => changeme ) ) Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Complex update $query = $dm->query("update User inc count = 1, inc views = 2, set username = 'jwage'"); Array ( [$inc] => Array ( [count] => 1 [views] => 2 ) [$set] => Array ( [username] => jwage ) ) Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • MongoDB ODM • Document Query Language (DQL) – atomic operators – skip and limit main results – skip and limit embedded documents – use dot notation for querying embedded documents – embed JSON values in your DQL syntax $query = $dm->query("update User pushAll groups = '[1, 2, 3]'"); Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Database Migrations • New DoctrineMigrationsBundle contains integration with the Doctrine Database Migrations project • Migrations have been completely re-written from Doctrine1 and are an extension of the database abstraction layer http://www.doctrine-project.org/projects/migrations Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Database Migrations • Migration classes: class Version20100416130401 extends AbstractMigration { public function up(Schema $schema) { } public function down(Schema $schema) { } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Database Migrations • Manually execute SQL for migrations: class Version20100416130422 extends AbstractMigration { public function up(Schema $schema) { $this->_addSql('CREATE TABLE addresses (id INT NOT NULL, street VARCHAR(255) NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB'); } public function down(Schema $schema) { $this->_addSql('DROP TABLE addresses'); } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Database Migrations • Use API of Schema objects to perform migration: 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'); } } Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Database Migrations • Check migrations status: $ ./doctrine migrations:status == Configuration >> Name: Doctrine Sandbox Migrations >> Configuration Source: /Users/jwage/Sites/doctrine2git/tools/sandbox/migrations.xml >> Version Table Name: doctrine_migration_versions >> Migrations Namespace: DoctrineMigrations >> Migrations Directory: /Users/jwage/Sites/doctrine2git/tools/sandbox/DoctrineMigrations >> Current Version: 2010-04-16 13:04:22 (20100416130422) >> Latest Version: 2010-04-16 13:04:22 (20100416130422) >> Executed Migrations: 0 >> Available Migrations: 1 >> New Migrations: 1 == Migration Versions >> 2010-04-16 13:04:01 (20100416130401) not migrated Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Database Migrations • Execute migration dry runs: $ ./doctrine migrations:migrate --dry-run Are you sure you wish to continue? y Executing dry run of migration up to 20100416130452 from 0 >> migrating 20100416130452 -> CREATE TABLE users (username VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL) ENGINE = InnoDB • Omit --dry-run to execute migration. Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Database Migrations • Specify a version number to revert to or 0 to revert all migrations: $ ./doctrine migrations:migrate 0 Are you sure you wish to continue? y Migrating down to 0 from 20100416130401 -- reverting 20100416130401 -> DROP TABLE users -- reverted Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Database Migrations • Write migration SQL file instead of executing: $ ./doctrine migrations:migrate --write-sql Executing dry run of migration up to 20100416130401 from 0 >> migrating 20100416130401 -> CREATE TABLE users (username VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL) ENGINE = InnoDB Writing migration file to "/path/to/sandbox/doctrine_migration_20100416130405.sql" • It would produce a file like: # Doctrine Migration File Generated on 2010-04-16 13:04:05 # Migrating from 0 to 20100416130422 # Version 20100416130401 CREATE TABLE users (username VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL) ENGINE = InnoDB; Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Database Migrations • Integration with ORM for generating migrations when you change your mapping information. Add a new property to your Entity: /** @Entity @Table(name="users") */ class User { /** * @var string $test */ private $test; // ... } • Run the migrations diff command: $ ./doctrine migrations:diff Generated new migration class to "/path/to/migrations/DoctrineMigrations/Version20100416130459.php" from schema differences. Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Database Migrations • The generated migration class looks like: class Version20100416130459 extends AbstractMigration { public function up(Schema $schema) { $this->_addSql('ALTER TABLE users ADD test VARCHAR(255) NOT NULL'); } public function down(Schema $schema) { $this->_addSql('ALTER TABLE users DROP test'); } } • It contains the SQL statements required to update your database with the schema changes. Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Database Migrations • Run migrate command to execute the generated migration: $ ./doctrine migrations:migrate • Now your database is up to date and contains the new column named test. Doctrine 2 www.doctrine-project.org www.sensiolabs.com
  • Questions? Jonathan H. Wage jonathan.wage@sensio.com sensiolabs.com | doctrine-project.org | sympalphp.org | jwage.com You should follow me on http://www.twitter.com/jwage for updates about Symfony, Doctrine and related developments. You can contact Jonathan about Doctrine and Open-Source or for training, consulting, application development, or business related questions at jonathan.wage@sensio.com Doctrine 2 www.doctrine-project.org www.sensiolabs.com