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

Symfony2. Database and Doctrine

  • 1.
  • 2.
  • 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 EntityClass // 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 useSymfonyComponentHttpFoundationResponse; 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()); }
  • 13.
  • 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 functionupdateAction($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 - querybuilder $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 namespaceVolcanoVideostatusBundleEntity; use DoctrineORMMapping as ORM; /** * @ORMEntity(repositoryClass="VolcanoVideostatusBundleRepositoryClipRepository") * @ORMTable(name="clip") */ class Clip { }
  • 20.
    Custom Repository //src/Volcano/VideostatusBundle/Repository/ClipRepository.php namespace VolcanoVideostatusBundleRepository; useDoctrineORMEntityRepository; 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(); } }
  • 21.
  • 22.
    Many To ManyAssociation /** * @ORMEntity */ class Clip { /** * @ORMManyToMany(targetEntity="Tag", inversedBy="clips") * @ORMJoinTable(name="clips_tags") **/ private $tags; public function __construct() { $this->groups = new ArrayCollection(); } }
  • 23.
    Many To ManyAssociation /** * @ORMEntity */ class Tag { /** * @ORMManyToMany(targetEntity="Clip", mappedBy="tags") **/ private $clips; public function __construct() { $this->clips = new ArrayCollection(); } }
  • 24.
    Many To ManyAssociation 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 functioncreateAction() { $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 publicfunction 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 DoctrineExtensions /** * @ORMEntity */ class Clip { /* * @GedmoSlug(fields={"title"}, unique=true) */ protected $slug; protected $title; }
  • 31.
    Gedmo 2 DoctrineExtensions 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 DoctrineExtensions ● Tree ● Translatable ● Sluggable ● Timestampable ● Loggable ● Softdeleteable ● Uploadable