clase 7 el modelo
DESCRIPTION
www.hydrascs.comTRANSCRIPT
El Modelo - Doctrine
Realizada por:Christian Aquino |@cj_aquinoDiego Ramirez |@thedarsideofit
Para: Hydras C&S |@hydras_csBasada en Libro Symfony 2 en español Nacho Pacheco y The Book
Conectándonos a la BD
# app/config/parameters.ymlparameters: database_driver: pdo_mysql database_host: localhost database_name: proyecto_de_prueba database_user: nombre_de_usuario database_password: password# app/config/config.ymldoctrine: dbal: driver: "%database_driver%" host: "%database_host%" dbname: "%database_name%" user: "%database_user%" password: "%database_password%"
php app/console doctrine:database:create
Creando nuestra primer Entidad
// src/Acme/StoreBundle/Entity/Product.phpnamespace Acme\StoreBundle\Entity;
class Product{ protected $name;
protected $price;
protected $description;}php app/console doctrine:generate:entity --entity="AcmeStoreBundle:Product" --fields="name:string(255) price:float description:text"
Podemos interactuar con la consola de symfony o pasar todo en una línea
Agregando datos de mapeo a nuestra entidad - Annotations// src/Acme/StoreBundle/Entity/Product.phpnamespace Acme\StoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/** * @ORM\Entity * @ORM\Table(name="product") */class Product{ /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id;
/** * @ORM\Column(type="string", length=100) */ protected $name;
/** * @ORM\Column(type="decimal", scale=2) */ protected $price;
/** * @ORM\Column(type="text") */ protected $description;}
Agregando datos de mapeo a nuestra entidad - YAML # src/Acme/StoreBundle/Resources/config/doctrine/Product.orm.ymlAcme\StoreBundle\Entity\Product: type: entity table: product id: id: type: integer generator: { strategy: AUTO } fields: name: type: string length: 100 price: type: decimal scale: 2 description: type: text
Agregando datos de mapeo a nuestra entidad - XML<!-- src/Acme/StoreBundle/Resources/config/doctrine/Product.orm.xml --><doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Acme\StoreBundle\Entity\Product" table="product"> <id name="id" type="integer" column="id"> <generator strategy="AUTO" /> </id> <field name="name" column="name" type="string" length="100" /> <field name="price" column="price" type="decimal" scale="2" /> <field name="description" column="description" type="text" /> </entity></doctrine-mapping>
Generando getters y setters
Podemos crear para todo el bundle o para varios bundles
php app/console doctrine:generate:entities Acme/StoreBundle/Entity/Product
php app/console doctrine:generate:entities AcmeStoreBundle php app/console doctrine:generate:entities Acme
Aplicando cambios a nuestro esquema
Si queremos ver el sql que genera el comando$ php app/console doctrine:schema:update --force --dump-sql
$ php app/console doctrine:schema:update --force
Persistiendo Nuestras Entidades// src/Acme/StoreBundle/Controller/DefaultController.php
// ...use Acme\StoreBundle\Entity\Product;use Symfony\Component\HttpFoundation\Response;
public function createAction(){ $product = new Product(); $product->setName('A Foo Bar'); $product->setPrice('19.99'); $product->setDescription('Lorem ipsum dolor');
$em = $this->getDoctrine()->getManager(); $em->persist($product); $em->flush();
return new Response('Created product id '.$product->getId());}
Recuperando informaciónpublic function showAction($id){ $product = $this->getDoctrine()->getEntityManager() ->getRepository('AcmeStoreBundle:Product') ->find($id);
if (!$product) { throw $this->createNotFoundException( 'No product found for id '.$id ); }
// ... haz algo, como pasar el objeto $product a una plantilla}
Recuperando información// consulta por la clave principal (generalmente 'id')$product = $repository->find($id);// nombres dinámicos de métodos para buscar un valor basad en columna$product = $repository->findOneById($id);$product = $repository->findOneByName('foo');// recupera TODOS los productos$products = $repository->findAll();// busca un grupo de productos basándose en el valor de una columna arbitraria$products = $repository->findByPrice(19.99);// consulta por un producto que coincide en nombre y precio$product = $repository->findOneBy(array('name' => 'foo', 'price' => 19.99));// pregunta por todos los productos en que coincide el nombre, ordenados por precio$product = $repository->findBy( array('name' => 'foo'), array('price', 'ASC'));
Eliminando un objeto
Consultando con DQL
$em->remove($product);$em->flush();
$em = $this->getDoctrine()->getEntityManager();$query = $em->createQuery( 'SELECT p FROM AcmeStoreBundle:Product p WHERE p.price > :price ORDER BY p.price ASC')->setParameter('price', '19.99');
$products = $query->getResult();
Usando el Query Builder$repository = $this->getDoctrine() ->getRepository('AcmeStoreBundle:Product');
$query = $repository->createQueryBuilder('p') ->where('p.price > :price') ->setParameter('price', '19.99') ->orderBy('p.price', 'ASC') ->getQuery();
$products = $query->getResult();
Agregando un Repositorio - Annotations// src/Acme/StoreBundle/Entity/Product.phpnamespace Acme\StoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/** * @ORM\Entity(repositoryClass="Acme\StoreBundle\Entity\ProductRepository") */class Product{ //...}
Agregando un RepositorioYAML
XML
# src/Acme/StoreBundle/Resources/config/doctrine/Product.orm.ymlAcme\StoreBundle\Entity\Product: type: entity repositoryClass: Acme\StoreBundle\Entity\ProductRepository # ...
<!-- src/Acme/StoreBundle/Resources/config/doctrine/Product.orm.xml -->
<!-- ... --><doctrine-mapping>
<entity name="Acme\StoreBundle\Entity\Product" repository-class="Acme\StoreBundle\Entity\ProductRepository"> <!-- ... --> </entity></doctrine-mapping>
Métodos Propios en el Repositorio// src/Acme/StoreBundle/Entity/ProductRepository.phpnamespace Acme\StoreBundle\Entity;
use Doctrine\ORM\EntityRepository;
class ProductRepository extends EntityRepository{ public function findAllOrderedByName() { return $this->getEntityManager() ->createQuery('SELECT p FROM AcmeStoreBundle:Product p ORDER BY p.name ASC') ->getResult(); }}
Relaciones de Entidades OneToMany// src/Acme/StoreBundle/Entity/Category.php// ...use Doctrine\Common\Collections\ArrayCollection;
class Category{ // ...
/** * @ORM\OneToMany(targetEntity="Product", mappedBy="category") */ protected $products;
public function __construct() { $this->products = new ArrayCollection(); }}
Relaciones de Entidades ManyToOne// src/Acme/StoreBundle/Entity/Product.php
// ...class Product{ // ...
/** * @ORM\ManyToOne(targetEntity="Category", inversedBy="products") * @ORM\JoinColumn(name="category_id", referencedColumnName="id") */ protected $category;}
Esquema general de la relación
Guardando objetos relacionadosuse Acme\StoreBundle\Entity\Category;use Acme\StoreBundle\Entity\Product;use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller{ public function createProductAction() { $category = new Category(); $category->setName('Main Products'); $product = new Product(); $product->setName('Foo'); $product->setPrice(19.99); // relaciona este producto a la categoría $product->setCategory($category); $em = $this->getDoctrine()->getManager(); $em->persist($category); $em->persist($product); $em->flush(); ...
Recuperando Objetos relacionados
public function showAction($id){ $product = $this->getDoctrine() ->getRepository('AcmeStoreBundle:Product') ->find($id); $categoryName = $product->getCategory()->getName();
// ...}public function showProductAction($id){ $category = $this->getDoctrine() ->getRepository('AcmeStoreBundle:Category') ->find($id);
$products = $category->getProducts();
// ...}
Evitando el lazy loading -JOINS
// src/Acme/StoreBundle/Entity/ProductRepository.phppublic function findOneByIdJoinedToCategory($id){ $query = $this->getEntityManager() ->createQuery(' SELECT p, c FROM AcmeStoreBundle:Product p JOIN p.category c WHERE p.id = :id' )->setParameter('id', $id);
try { return $query->getSingleResult(); } catch (\Doctrine\ORM\NoResultException $e) { return null; }}