SlideShare une entreprise Scribd logo
1  sur  32
Télécharger pour lire hors ligne
Symfony2
Database and Doctrine
ORM (Object-relational mapping)
Configuring the Database
# app/config/parameters.yml
parameters:
database_driver: pdo_mysql
database_host: localhost
database_name: test_project
database_user: root
database_password: password
Creating the database
$ php app/console doctrine:database:create
Creating an Entity Class
// src/Volcano/VideostatusBundle/Entity/Clip.php
namespace VolcanoVideostatusBundleEntity;
class Clip
{
protected $id;
protected $url;
protected $timeStart;
protected $timeFinish;
}
Creating Mapping Info
// src/Volcano/VideostatusBundle/Entity/Clip.php
namespace VolcanoVideostatusBundleEntity;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity
* @ORMTable(name="clip", indexes={
* @ORMIndex(name="clip_url_idx",columns={"url"}
* })
*/
class Clip
{ }
Creating Mapping Info
/**
* @ORMId
* @ORMColumn(type="integer")
* @ORMGeneratedValue(strategy="AUTO")
*/
protected $id;
Creating Mapping Info
/**
* @ORMColumn(type="string", length=255)
*/
protected $url;
Creating Mapping Info
/**
* @ORMColumn(name="time_start", type="integer")
*/
protected $timeStart;
Generating Setters and
Getters
$ php app/console doctrine:generate:entities |
VolcanoVideostatusBundleEntityClip
Creating the schema
$ php app/console doctrine:schema:update --force
Persisting object
// src/Volcano/VideostatusBundle/Controller/ClipController.php
use SymfonyComponentHttpFoundationResponse;
use VolcanoVideostatusBundleEntityClip;
public function createAction()
{
$clip = new Clip();
$clip->setUrl('http://www.youtube.com/watch?v=PYtXuBN1Hvc');
$clip->setTimeStart(52);
$clip->setTimeFinish(54);
$em = $this->getDoctrine()->getManager();
$em->persist($clip);
$em->flush();
return new Response('Created clip id '.$clip->getId());
}
Unit Of Work
DB
Entity
EM
Persist
Application
Update
Delete
Flush
Fetching object
$repository = $this->getDoctrine()
->getRepository('VolcanoVideostatusBundle:Clip');
$clip = $repository->find($id);
$clip = $repository->findOneByUrl('http://www.youtube.com/watch?v=PYtXuBN1Hvc');
$clips = $repository->findByUrl('http://www.youtube.com/watch?v=PYtXuBN1Hvc');
$clips = $repository->findAll();
$clips = $repository->findBy(
array('url' => 'http://www.youtube.com/watch?v=PYtXuBN1Hvc'),
array('timeStart' => '0')
);
Updating object
public function updateAction($id)
{
$em = $this->getDoctrine()->getManager();
$clip = $em->getRepository('VolcanoVideostatusBundle:Clip')->find($id);
if (!$clip) {
throw $this->createNotFoundException(
'No clip found for id '.$id
);
}
$clip->setTimeFinish(55);
$em->flush();
return $this->redirect($this->generateUrl('homepage'));
}
Deleting object
$em = $this->getDoctrine()->getManager();
$clip = $em->getRepository('VolcanoVideostatusBundle:
Clip')
->find($id);
$em->remove($clip);
$em->flush();
DQL
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
'SELECT c FROM VolcanoVideostatusBundle:Clip c WHERE c.
timeFinish - c.timeStart > :delta ORDER BY p.id ASC'
)->setParameter('delta', 10);
$clips = $query->getResult();
DQL - query builder
$repository = $this->getDoctrine()
->getRepository('VolcanoVideostatusBundle:Clip');
$query = $repository->createQueryBuilder('c')
->where('c.timeFinish - c.timeStart > :delta')
->setParameter('delta', 10)
->orderBy('c.id', 'ASC')
->getQuery();
$clips = $query->getResult();
Custom Repository
// src/Volcano/VideostatusBundle/Entity/Clip.php
namespace VolcanoVideostatusBundleEntity;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity(repositoryClass="VolcanoVideostatusBundleRepositoryClipRepository")
* @ORMTable(name="clip")
*/
class Clip
{ }
Custom Repository
//src/Volcano/VideostatusBundle/Repository/ClipRepository.php
namespace VolcanoVideostatusBundleRepository;
use DoctrineORMEntityRepository;
class ClipRepository extends EntityRepository
{
public function findAllLongerThan($length)
{
$query = $repository->createQueryBuilder('c')
->where('c.timeFinish - c.timeStart > :delta')
->setParameter('delta', intval($length))
->orderBy('c.id', 'ASC')
->getQuery();
return $query->getResult();
}
}
Relationships
Many To Many
Clip
Fun
Котята
Сиськи
Clip
Many To Many Association
/**
* @ORMEntity
*/
class Clip
{
/**
* @ORMManyToMany(targetEntity="Tag", inversedBy="clips")
* @ORMJoinTable(name="clips_tags")
**/
private $tags;
public function __construct() {
$this->groups = new ArrayCollection();
}
}
Many To Many Association
/**
* @ORMEntity
*/
class Tag
{
/**
* @ORMManyToMany(targetEntity="Clip", mappedBy="tags")
**/
private $clips;
public function __construct() {
$this->clips = new ArrayCollection();
}
}
Many To Many Association
CREATE TABLE Clip (
id INT AUTO_INCREMENT NOT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB;
CREATE TABLE clips_tags (
clip_id INT NOT NULL,
tag_id INT NOT NULL,
PRIMARY KEY(clip_id, tag_id)
) ENGINE = InnoDB;
CREATE TABLE Tag (
id INT AUTO_INCREMENT NOT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB;
ALTER TABLE clips_tags ADD FOREIGN KEY (clip_id) REFERENCES Clip(id);
ALTER TABLE clips_tags ADD FOREIGN KEY (tag_id) REFERENCES Tag(id);
Persisting object
public function createAction()
{
$clip = new Clip();
$clip->setUrl('http://www.youtube.com/watch?v=PYtXuBN1Hvc');
$tag1 = new Tag();
$tag1->setName('Fun');
$tag2 = new Tag();
$tag2->setName('Котята');
$clip->addTag($tag1);
$clip->addTag($tag2);
$em = $this->getDoctrine()->getManager();
$em->persist($tag1);
$em->persist($tag2);
$em->persist($clip);
$em->flush();
return new Response('Created clip id '.$clip->getId());
}
Fetching Related Objects
public function showClipTagsAction($id)
{
$clip = $this->getDoctrine()
->getRepository('VolcanoVideostatusBundle:Clip')->find($id);
$tags = $clip->getTags();
return array('tags' => $tags);
}
<div class="tags">
<div class="tags-list">
{% for tag in tags %}
<a class="label" href="#">{{tag.name}}</a>
{% endfor %}
</div>
</div>
Fetching Related Objects
<?php
// src/Volcano/VideostatusBundle/Entity/ClipRepository.php
public function findOneByIdJoinedToTags($id)
{
$query = $this->getEntityManager()
->createQuery('
SELECT c, t FROM VideostatusBundle:Clip c
JOIN c.tags t
WHERE c.id = :id'
)->setParameter('id', $id);
try {
return $query->getSingleResult();
} catch (DoctrineORMNoResultException $e) {
return null;
}
}
Lifecycle Callbacks
/**
* @ORMEntity()
* @ORMHasLifecycleCallbacks()
*/
class Clip
{
//....
/**
* @ORMPrePersist
*/
public function setCreatedValue()
{
$this->created = new DateTime();
}
}
Lifecycle Callbacks
● preRemove
● postRemove
● prePersist
● postPersist
● preUpdate
● postUpdate
Gedmo 2 Doctrine Extensions
/**
* @ORMEntity
*/
class Clip
{
/*
* @GedmoSlug(fields={"title"}, unique=true)
*/
protected $slug;
protected $title;
}
Gedmo 2 Doctrine Extensions
class Clip
{
/**
* @GedmoTimestampable(on="create")
* @ORMColumn(name="created", type="datetime")
*/
private $created;
/**
* @ORMColumn(name="updated", type="datetime")
* @GedmoTimestampable(on="update")
*/
private $updated;
}
Gedmo 2 Doctrine Extensions
● Tree
● Translatable
● Sluggable
● Timestampable
● Loggable
● Softdeleteable
● Uploadable

Contenu connexe

Tendances

Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
Fabien Potencier
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
Kris Wallsmith
 
Introduction to Twig
Introduction to TwigIntroduction to Twig
Introduction to Twig
markstory
 
Awash in a sea of connections
Awash in a sea of connectionsAwash in a sea of connections
Awash in a sea of connections
Galen Charlton
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
Fabien Potencier
 

Tendances (20)

Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
Indices APIs - Elasticsearch Reference
Indices APIs - Elasticsearch ReferenceIndices APIs - Elasticsearch Reference
Indices APIs - Elasticsearch Reference
 
Intro to Advanced JavaScript
Intro to Advanced JavaScriptIntro to Advanced JavaScript
Intro to Advanced JavaScript
 
Maintaining your own branch of Drupal core
Maintaining your own branch of Drupal coreMaintaining your own branch of Drupal core
Maintaining your own branch of Drupal core
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniques
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniques
 
Neatly folding-a-tree
Neatly folding-a-treeNeatly folding-a-tree
Neatly folding-a-tree
 
My shell
My shellMy shell
My shell
 
Putting the Cat in the Catalogue: A Feline-Inspired OPAC Theme For Koha
Putting the Cat in the Catalogue: A Feline-Inspired OPAC Theme For KohaPutting the Cat in the Catalogue: A Feline-Inspired OPAC Theme For Koha
Putting the Cat in the Catalogue: A Feline-Inspired OPAC Theme For Koha
 
Plugin jQuery, Design Patterns
Plugin jQuery, Design PatternsPlugin jQuery, Design Patterns
Plugin jQuery, Design Patterns
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginners
 
Tax management-system
Tax management-systemTax management-system
Tax management-system
 
Introduction to Twig
Introduction to TwigIntroduction to Twig
Introduction to Twig
 
Awash in a sea of connections
Awash in a sea of connectionsAwash in a sea of connections
Awash in a sea of connections
 
Intro to php
Intro to phpIntro to php
Intro to php
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
New in cakephp3
New in cakephp3New in cakephp3
New in cakephp3
 
Intro to PHP
Intro to PHPIntro to PHP
Intro to PHP
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
 

En vedette

Symfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationSymfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 Integration
Jonathan Wage
 
Doctrine In The Real World sflive2011 Paris
Doctrine In The Real World sflive2011 ParisDoctrine In The Real World sflive2011 Paris
Doctrine In The Real World sflive2011 Paris
Jonathan Wage
 

En vedette (9)

Understanding Doctrine at True North PHP 2013
Understanding Doctrine at True North PHP 2013Understanding Doctrine at True North PHP 2013
Understanding Doctrine at True North PHP 2013
 
Symfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationSymfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 Integration
 
ORO Meetups - Doctrine Events
ORO Meetups - Doctrine EventsORO Meetups - Doctrine Events
ORO Meetups - Doctrine Events
 
ORM dont kill your DB, developers do
ORM dont kill your DB, developers doORM dont kill your DB, developers do
ORM dont kill your DB, developers do
 
Doctrine ORM & model
Doctrine ORM & modelDoctrine ORM & model
Doctrine ORM & model
 
Effective Doctrine2: Performance Tips for Symfony2 Developers
Effective Doctrine2: Performance Tips for Symfony2 DevelopersEffective Doctrine2: Performance Tips for Symfony2 Developers
Effective Doctrine2: Performance Tips for Symfony2 Developers
 
www.AulasDeFisicaApoio.com - Física – Exercícios Complementares de Eletricidade
www.AulasDeFisicaApoio.com  - Física – Exercícios Complementares de Eletricidadewww.AulasDeFisicaApoio.com  - Física – Exercícios Complementares de Eletricidade
www.AulasDeFisicaApoio.com - Física – Exercícios Complementares de Eletricidade
 
Doctrine In The Real World sflive2011 Paris
Doctrine In The Real World sflive2011 ParisDoctrine In The Real World sflive2011 Paris
Doctrine In The Real World sflive2011 Paris
 
Doctrine 2 - Not The Same Old Php Orm
Doctrine 2 - Not The Same Old Php OrmDoctrine 2 - Not The Same Old Php Orm
Doctrine 2 - Not The Same Old Php Orm
 

Similaire à Symfony2. Database and Doctrine

Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme development
Tammy Hart
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
Jeremy Kendall
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Jeremy Kendall
 
Legacy applications - 4Developes konferencja, Piotr Pasich
Legacy applications  - 4Developes konferencja, Piotr PasichLegacy applications  - 4Developes konferencja, Piotr Pasich
Legacy applications - 4Developes konferencja, Piotr Pasich
Piotr Pasich
 
Commenting in Agile Development
Commenting in Agile DevelopmentCommenting in Agile Development
Commenting in Agile Development
Jan Rybák Benetka
 

Similaire à Symfony2. Database and Doctrine (20)

New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
 
Rest in practice con Symfony2
Rest in practice con Symfony2Rest in practice con Symfony2
Rest in practice con Symfony2
 
Migrare da symfony 1 a Symfony2
 Migrare da symfony 1 a Symfony2  Migrare da symfony 1 a Symfony2
Migrare da symfony 1 a Symfony2
 
Let ColdFusion ORM do the work for you!
Let ColdFusion ORM do the work for you!Let ColdFusion ORM do the work for you!
Let ColdFusion ORM do the work for you!
 
Doctrine in FLOW3
Doctrine in FLOW3Doctrine in FLOW3
Doctrine in FLOW3
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme development
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_Tool
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
 
TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase framework
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
 
Demystifying Maven
Demystifying MavenDemystifying Maven
Demystifying Maven
 
Legacy applications - 4Developes konferencja, Piotr Pasich
Legacy applications  - 4Developes konferencja, Piotr PasichLegacy applications  - 4Developes konferencja, Piotr Pasich
Legacy applications - 4Developes konferencja, Piotr Pasich
 
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
Keeping It Small with Slim
Keeping It Small with SlimKeeping It Small with Slim
Keeping It Small with Slim
 
Nick: A Nearly Headless CMS
Nick: A Nearly Headless CMSNick: A Nearly Headless CMS
Nick: A Nearly Headless CMS
 
Softshake - Offline applications
Softshake - Offline applicationsSoftshake - Offline applications
Softshake - Offline applications
 
Commenting in Agile Development
Commenting in Agile DevelopmentCommenting in Agile Development
Commenting in Agile Development
 

Dernier

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Dernier (20)

Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 

Symfony2. Database and Doctrine

  • 3. Configuring the Database # app/config/parameters.yml parameters: database_driver: pdo_mysql database_host: localhost database_name: test_project database_user: root database_password: password
  • 4. Creating the database $ php app/console doctrine:database:create
  • 5. Creating an Entity Class // src/Volcano/VideostatusBundle/Entity/Clip.php namespace VolcanoVideostatusBundleEntity; class Clip { protected $id; protected $url; protected $timeStart; protected $timeFinish; }
  • 6. Creating Mapping Info // src/Volcano/VideostatusBundle/Entity/Clip.php namespace VolcanoVideostatusBundleEntity; use DoctrineORMMapping as ORM; /** * @ORMEntity * @ORMTable(name="clip", indexes={ * @ORMIndex(name="clip_url_idx",columns={"url"} * }) */ class Clip { }
  • 7. Creating Mapping Info /** * @ORMId * @ORMColumn(type="integer") * @ORMGeneratedValue(strategy="AUTO") */ protected $id;
  • 8. Creating Mapping Info /** * @ORMColumn(type="string", length=255) */ protected $url;
  • 9. Creating Mapping Info /** * @ORMColumn(name="time_start", type="integer") */ protected $timeStart;
  • 10. Generating Setters and Getters $ php app/console doctrine:generate:entities | VolcanoVideostatusBundleEntityClip
  • 11. Creating the schema $ php app/console doctrine:schema:update --force
  • 12. Persisting object // src/Volcano/VideostatusBundle/Controller/ClipController.php use SymfonyComponentHttpFoundationResponse; use VolcanoVideostatusBundleEntityClip; public function createAction() { $clip = new Clip(); $clip->setUrl('http://www.youtube.com/watch?v=PYtXuBN1Hvc'); $clip->setTimeStart(52); $clip->setTimeFinish(54); $em = $this->getDoctrine()->getManager(); $em->persist($clip); $em->flush(); return new Response('Created clip id '.$clip->getId()); }
  • 14. Fetching object $repository = $this->getDoctrine() ->getRepository('VolcanoVideostatusBundle:Clip'); $clip = $repository->find($id); $clip = $repository->findOneByUrl('http://www.youtube.com/watch?v=PYtXuBN1Hvc'); $clips = $repository->findByUrl('http://www.youtube.com/watch?v=PYtXuBN1Hvc'); $clips = $repository->findAll(); $clips = $repository->findBy( array('url' => 'http://www.youtube.com/watch?v=PYtXuBN1Hvc'), array('timeStart' => '0') );
  • 15. Updating object public function updateAction($id) { $em = $this->getDoctrine()->getManager(); $clip = $em->getRepository('VolcanoVideostatusBundle:Clip')->find($id); if (!$clip) { throw $this->createNotFoundException( 'No clip found for id '.$id ); } $clip->setTimeFinish(55); $em->flush(); return $this->redirect($this->generateUrl('homepage')); }
  • 16. Deleting object $em = $this->getDoctrine()->getManager(); $clip = $em->getRepository('VolcanoVideostatusBundle: Clip') ->find($id); $em->remove($clip); $em->flush();
  • 17. DQL $em = $this->getDoctrine()->getManager(); $query = $em->createQuery( 'SELECT c FROM VolcanoVideostatusBundle:Clip c WHERE c. timeFinish - c.timeStart > :delta ORDER BY p.id ASC' )->setParameter('delta', 10); $clips = $query->getResult();
  • 18. DQL - query builder $repository = $this->getDoctrine() ->getRepository('VolcanoVideostatusBundle:Clip'); $query = $repository->createQueryBuilder('c') ->where('c.timeFinish - c.timeStart > :delta') ->setParameter('delta', 10) ->orderBy('c.id', 'ASC') ->getQuery(); $clips = $query->getResult();
  • 19. Custom Repository // src/Volcano/VideostatusBundle/Entity/Clip.php namespace VolcanoVideostatusBundleEntity; use DoctrineORMMapping as ORM; /** * @ORMEntity(repositoryClass="VolcanoVideostatusBundleRepositoryClipRepository") * @ORMTable(name="clip") */ class Clip { }
  • 20. Custom Repository //src/Volcano/VideostatusBundle/Repository/ClipRepository.php namespace VolcanoVideostatusBundleRepository; use DoctrineORMEntityRepository; class ClipRepository extends EntityRepository { public function findAllLongerThan($length) { $query = $repository->createQueryBuilder('c') ->where('c.timeFinish - c.timeStart > :delta') ->setParameter('delta', intval($length)) ->orderBy('c.id', 'ASC') ->getQuery(); return $query->getResult(); } }
  • 22. Many To Many Association /** * @ORMEntity */ class Clip { /** * @ORMManyToMany(targetEntity="Tag", inversedBy="clips") * @ORMJoinTable(name="clips_tags") **/ private $tags; public function __construct() { $this->groups = new ArrayCollection(); } }
  • 23. Many To Many Association /** * @ORMEntity */ class Tag { /** * @ORMManyToMany(targetEntity="Clip", mappedBy="tags") **/ private $clips; public function __construct() { $this->clips = new ArrayCollection(); } }
  • 24. Many To Many Association CREATE TABLE Clip ( id INT AUTO_INCREMENT NOT NULL, PRIMARY KEY(id) ) ENGINE = InnoDB; CREATE TABLE clips_tags ( clip_id INT NOT NULL, tag_id INT NOT NULL, PRIMARY KEY(clip_id, tag_id) ) ENGINE = InnoDB; CREATE TABLE Tag ( id INT AUTO_INCREMENT NOT NULL, PRIMARY KEY(id) ) ENGINE = InnoDB; ALTER TABLE clips_tags ADD FOREIGN KEY (clip_id) REFERENCES Clip(id); ALTER TABLE clips_tags ADD FOREIGN KEY (tag_id) REFERENCES Tag(id);
  • 25. Persisting object public function createAction() { $clip = new Clip(); $clip->setUrl('http://www.youtube.com/watch?v=PYtXuBN1Hvc'); $tag1 = new Tag(); $tag1->setName('Fun'); $tag2 = new Tag(); $tag2->setName('Котята'); $clip->addTag($tag1); $clip->addTag($tag2); $em = $this->getDoctrine()->getManager(); $em->persist($tag1); $em->persist($tag2); $em->persist($clip); $em->flush(); return new Response('Created clip id '.$clip->getId()); }
  • 26. Fetching Related Objects public function showClipTagsAction($id) { $clip = $this->getDoctrine() ->getRepository('VolcanoVideostatusBundle:Clip')->find($id); $tags = $clip->getTags(); return array('tags' => $tags); } <div class="tags"> <div class="tags-list"> {% for tag in tags %} <a class="label" href="#">{{tag.name}}</a> {% endfor %} </div> </div>
  • 27. Fetching Related Objects <?php // src/Volcano/VideostatusBundle/Entity/ClipRepository.php public function findOneByIdJoinedToTags($id) { $query = $this->getEntityManager() ->createQuery(' SELECT c, t FROM VideostatusBundle:Clip c JOIN c.tags t WHERE c.id = :id' )->setParameter('id', $id); try { return $query->getSingleResult(); } catch (DoctrineORMNoResultException $e) { return null; } }
  • 28. Lifecycle Callbacks /** * @ORMEntity() * @ORMHasLifecycleCallbacks() */ class Clip { //.... /** * @ORMPrePersist */ public function setCreatedValue() { $this->created = new DateTime(); } }
  • 29. Lifecycle Callbacks ● preRemove ● postRemove ● prePersist ● postPersist ● preUpdate ● postUpdate
  • 30. Gedmo 2 Doctrine Extensions /** * @ORMEntity */ class Clip { /* * @GedmoSlug(fields={"title"}, unique=true) */ protected $slug; protected $title; }
  • 31. Gedmo 2 Doctrine Extensions class Clip { /** * @GedmoTimestampable(on="create") * @ORMColumn(name="created", type="datetime") */ private $created; /** * @ORMColumn(name="updated", type="datetime") * @GedmoTimestampable(on="update") */ private $updated; }
  • 32. Gedmo 2 Doctrine Extensions ● Tree ● Translatable ● Sluggable ● Timestampable ● Loggable ● Softdeleteable ● Uploadable