SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.
SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.
Successfully reported this slideshow.
Activate your 14 day free trial to unlock unlimited reading.
3.
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
4.
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
5.
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
6.
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
7.
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
9.
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
10.
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
11.
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
12.
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
13.
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
14.
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
16.
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
17.
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
18.
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
19.
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
20.
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
21.
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
22.
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
23.
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
24.
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
25.
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
26.
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
27.
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
28.
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
29.
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
30.
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
31.
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
32.
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
34.
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
35.
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
36.
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
43.
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
44.
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
45.
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
46.
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
47.
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
49.
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
50.
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
51.
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
52.
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
53.
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
54.
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
55.
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