反映了Doctrine 2.2中的MySQL多态关联 [英] Reflect MySQL polymorphic association in Doctrine 2.2

查看:162
本文介绍了反映了Doctrine 2.2中的MySQL多态关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Doctrine 2.2.0和Codeigniter。我是新手(或一般的ORM)。



我正在基于YAML文件设置实体和代理类,工作正常。我的Doctrine类在我的DB中反映了一个多态关联的问题。我正在寻找一个关于如何在Doctrine中实现以下多态关联的具体示例。



在我的数据库中,我有一个称为产品的表。根据字段 object_type object_id 的值,我想将其与表格视频或表格中的记录相关联汽车(我简化了这里)。我想保持两个产品类型在两个单独的表,因为一个与其他表无关,这两个表与其他表相关。



我看了原则继承文件等的例子,但似乎并没有帮助我。 如果可能,我想避免将列描述和价格添加到表视频和汽车



非常感谢!

  |表: 
| --------------------------------------------- -------- |
| ID |描述|价格| object_type | object_id |
| --------------------------------------------- -------- |
| 1 |视频| 20.00 |视频| 12 |
| 2 |一辆车| 159.00 |车| 5 |

|表:视频|
| -------------------------------------------- |
| ID |文件名| artist_id |日期|
| -------------------------------------------- |
| 12 | somename.mp4 | 189 | 2011-02-15 |

|表:汽车|
| ------------------------------ |
| ID | brand_id |模型|年|
| ------------------------------ |
| 5 | 17 |阿斯特拉2010 |


解决方案

自己找到解决方案。下面列出了我所做的不同步骤。这个答案是非常大的,但我尽可能的完整。



最重要的是在产品YAML文件中 inheritanceType:JOINED discriminatorColumn: discriminatorMap:和Video and Car实体类 class视频扩展产品 class Car extends Product



1)DB模式



  CREATE TABLE IF NOT EXISTS`artists`(
`id` int(11)NOT NULL AUTO_INCREMENT,
`name` varchar(255)NOT NULL,
PRIMARY KEY(`id`)
)ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS`brands`(
`id` int(11)NOT NULL AUTO_INCREMENT,
`name` varchar(255)NOT NULL,
PRIMARY KEY(`id`)
)ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS`cars`(
`id` int(11)NOT NULL,
`model` varchar(255)NOT NULL,
` release_date` date NOT NULL,
`brand_id` int(11)NOT NULL,
PRIMARY KEY(`id`)
)ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS`products`(
`id` int(11)NOT NULL AUTO_INCREMENT,
`description` varchar(255)NOT NULL,
`price` double NOT NULL,
`object_type` varchar(255)NOT NULL,
PRIMARY KEY(`id`)
)ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS`video`(
`id` int(11)NOT NULL,
`file_name` varchar(255)NOT NULL,
` release_date` date NOT NULL,
`artist_id` int(11)NOT NULL,
PRIMARY KEY(`id`)
)ENGINE = InnoDB;



2)原则YAML文件(您需要从中创建实体和代理类)



Entities.Artist.dcm.yml

 实体\艺术家:
类型:实体
表:艺术家
id:
id:
类型:整数
主要:真
notnull :true
生成器:
策略:AUTO
字段:
名称:
类型:string(255)
notnull:true
oneToMany:
视频:
targetEntity:视频
mappedBy:artist
选项:
字符集:utf8
类型:InnoDB

Entities.Brand.dcm.yml

  Entities\Brand:
类型:实体
表:品牌
id:
id:
类型:整数
主: true
notnull:true
生成器:
策略:AUTO
字段:
名称:
类型:string(255)
notnull:true
oneToMany:
汽车:
targetEntity:Car
mappedBy:品牌
选项:
charset:utf8
类型:InnoDB

Entities.Car.dcm.yml

 实体\Car:
类型:实体
表:汽车
字段:
模型:
类型: string
notnull:true
release_date:
type:date
notnull:true
oneToOne:#unidirectional
品牌:
targetEntity:品牌
joinColumns:
brand_id:
referencedColumnName:id
选项:
charset:utf8
类型:Inno DB

Entities.Product.dcm.yml

 实体\产品:
类型:实体
表:products
id:
id:
类型:string
primary:true
notnull:true
生成器:
策略:AUTO
字段:
描述:
类型:string(255)
notnull:true
价格:
类型:decimal
notnull:true
继承类型:JOINED
discriminatorColumn:
名称:object_type
type:string
length:255
discriminatorMap:
video:video
car:Car
options:
charset:utf8
类型:InnoDB

Entities.Video.dcm.yml / p>

  Entities\Video:
type:entity
tab le:videos
fields:
file_name:
type:string
notnull:true
release_date:
type:date
notnull:true
oneToOne:#unidirectional
艺术家:
targetEntity:Artist
joinColumns:
artist_id:
referencedColumnName:id
options:
charset :utf8
类型:InnoDB



3)创建实体和代理类



我使用CodeIgniter。 我' ve使用Joel Verhagen的优秀指南



!重要的是您可以扩展视频和汽车产品 - 请参见下文!



这导致以下实体类



Artist.php





 命名空间实体; 

使用Doctrine\ORM\Mapping作为ORM;

/ **
* Entities\Artist
*
* @ ORM\Table(name =artists)
* @ ORM\\ \\Entity
* /
class艺术家
{
/ **
* @var整数$ id
*
* @ ORM\列(name =id,type =integer)
* @ ORM\Id
* @ ORM\GeneratedValue(strategy =IDENTITY)
* /
private $ id;

/ **
* @var string $ name
*
* @ ORM\Column(name =name,type =string,length = 255)
* /
private $ name;

/ **
* @var \Doctrine\Common\Collections\ArrayCollection
*
* @ ORM\OneToMany(targetEntity =Entities \Video,mappedBy =艺术家)
* /
私人视频;

public function __construct()
{
$ this-> videos = new \Doctrine\Common\Collections\ArrayCollection();
}

/ **
*获取id
*
* @return integer
* /
public function getId )
{
return $ this-> id;
}

/ **
*设置名称
*
* @param string $ name
* @return艺术家
* /
public function setName($ name)
{
$ this-> name = $ name;
return $ this;
}

/ **
*获取名称
*
* @return string
* /
public function getName )
{
return $ this-> name;
}

/ **
*添加视频
*
* @param Entities\Video $ videos
* /
public function addVideo(\Entities\Video $ videos)
{
$ this-> videos [] = $ videos;
}

/ **
*获取视频
*
* @return Doctrine\Common\Collections\Collection
* /
public function getVideos()
{
return $ this-> videos;
}
}

Brand.php / p>



 命名空间实体; 

使用Doctrine\ORM\Mapping作为ORM;

/ **
* Entities\Brand
*
* @ ORM\Table(name =brands)
* @ ORM\\ \\Entity
* /
class品牌
{
/ **
* @var整数$ id
*
* @ ORM\列(name =id,type =integer)
* @ ORM\Id
* @ ORM\GeneratedValue(strategy =IDENTITY)
* /
private $ id;

/ **
* @var string $ name
*
* @ ORM\Column(name =name,type =string,length = 255)
* /
private $ name;

/ **
* @var \Doctrine\Common\Collections\ArrayCollection
*
* @ ORM\OneToMany(targetEntity =Entities \Car,mappedBy =brand)
* /
private $ cars;

public function __construct()
{
$ this-> cars = new \Doctrine\Common\Collections\ArrayCollection();
}

/ **
*获取id
*
* @return integer
* /
public function getId )
{
return $ this-> id;
}

/ **
*设定名称
*
* @param string $ name
* @return品牌
* /
public function setName($ name)
{
$ this-> name = $ name;
return $ this;
}

/ **
*获取名称
*
* @return string
* /
public function getName )
{
return $ this-> name;
}

/ **
*添加汽车
*
* @param实体\Car $ cars
* /
public function addCar(\Entities\Car $ cars)
{
$ this-> cars [] = $ cars;
}

/ **
*获取汽车
*
* @return Doctrine\Common\Collections\Collection
* /
public function getCars()
{
return $ this-> cars;
}
}

Car.php / p>



 命名空间实体; 

使用Doctrine\ORM\Mapping作为ORM;

/ **
* Entities\Car
*
* @ ORM\Table(name =cars)
* @ ORM\\ \\ Entity
* /
class Car extends Product //重要的是Car扩展产品
{
/ **
* @var string $ model
*
* @ ORM\Column(name =model,type =string)
* /
private $ model;

/ **
* @var date $ release_date
*
* @ ORM\Column(name =release_date,type =date)
* /
private $ release_date;

/ **
* @var Entities\Brand
*
* @ ORM\OneToOne(targetEntity =Entities\Brand)
* @ ORM\JoinColumns({
* @ ORM\JoinColumn(name =brand_id,referencedColumnName =id,unique = true)
*})
* /
私人品牌;


/ **
*设置模型
*
* @param string $ model
* @return Car
* /
public function setModel($ model)
{
$ this-> model = $ model;
return $ this;
}

/ **
*获取模型
*
* @return string
* /
public function getModel )
{
return $ this-> model;
}

/ **
*设置release_date
*
* @param date $ releaseDate
* @return Car
* /
public function setReleaseDate($ releaseDate)
{
$ this-> release_date = $ releaseDate;
return $ this;
}

/ **
*获取release_date
*
* @return date
* /
public function getReleaseDate )
{
return $ this-> release_date;
}

/ **
*设置品牌
*
* @param Entities\Brand $ brand
* @return Car
* /
public function setBrand(\Entities\Brand $ brand = null)
{
$ this-> brand = $ brand;
return $ this;
}

/ **
*获取品牌
*
* @return Entities\Brand
* /
public function getBrand()
{
return $ this->品牌;
}
}

Product.php / p>



 命名空间实体; 

使用Doctrine\ORM\Mapping作为ORM;

/ **
* Entities\Product
*
* @ ORM\Table(name =products)
* @ ORM\\ \\ InheritanceType(JOINED)
* @ ORM\\DiscriminatorColumn(name =,type =,length =)
* @ ORM\DiscriminatorMap({video=Entities\\ \\ Video,car=Entities\Car})
* @ ORM\Entity
* /
class Product
{
/ **
* @var string $ id
*
* @ ORM\Column(name =id,type =string)
* @ ORM\Id
* @ ORM\GeneratedValue(strategy =IDENTITY)
* /
private $ id;

/ **
* @var string $ description
*
* @ ORM\Column(name =description,type =string,length = 255)
* /
private $ description;

/ **
* @var decimal decimal $ price
*
* @ ORM\Column(name =price,type =decimal)
* /
私人$价格;


/ **
*获取id
*
* @return string
* /
public function getId()
{
return $ this-> id;
}

/ **
*设置描述
*
* @param string $ description
* @return产品
* /
public function setDescription($ description)
{
$ this-> description = $ description;
return $ this;
}

/ **
*获取描述
*
* @return string
* /
public function getDescription )
{
return $ this-> description;
}

/ **
*设定价格
*
* @param decimal $ price
* @return产品
* /
public function setPrice($ price)
{
$ this-> price = $ price;
return $ this;
}

/ **
*获取价格
*
* @return decimal
* /
public function getPrice )
{
return $ this-> price;
}
}

Video.php / p>



 命名空间实体; 

使用Doctrine\ORM\Mapping作为ORM;

/ **
* Entities\Video
*
* @ ORM\Table(name =videos)
* @ ORM\\ \\Entity
* /
类视频扩展产品//视频延伸的重要产品
{
/ **
* @var string $ file_name
*
* @ ORM\Column(name =file_name,type =string)
* /
private $ file_name;

/ **
* @var date $ release_date
*
* @ ORM\Column(name =release_date,type =date)
* /
private $ release_date;

/ **
* @var Entities\Artist
*
* @ ORM\OneToOne(targetEntity =Entities\Artist)
* @ ORM\JoinColumns({
* @ ORM\JoinColumn(name =artist_id,referencedColumnName =id,unique = true)
*})
* /
私人$艺术家;


/ **
*设置文件名
*
* @param string $ fileName
* @return视频
* /
public function setFileName($ fileName)
{
$ this-> file_name = $ fileName;
return $ this;
}

/ **
*获取文件名
*
* @return string
* /
public function getFileName )
{
return $ this-> file_name;
}

/ **
*设置release_date
*
* @param date $ releaseDate
* @return视频
* /
public function setReleaseDate($ releaseDate)
{
$ this-> release_date = $ releaseDate;
return $ this;
}

/ **
*获取release_date
*
* @return date
* /
public function getReleaseDate )
{
return $ this-> release_date;
}

/ **
*设置艺术家
*
* @param实体\艺术家$艺术家
* @return视频
* /
public function setArtist(\Entities\Artist $ artist = null)
{
$ this-> artist = $ artist;
return $ this;
}

/ **
*获取艺术家
*
* @return Entities\Artist
* /
public function getArtist()
{
return $ this-> artist;
}
}



3)创建一个新的汽车和一个新的视频



这是我的CodeIgniter控制器中的内容。该代码假定您已经创建了一个名为Metallica的艺术家,以及名称为Ford的品牌。





  public function createVideo()
{
//实例化新的Entities\Video对象
$ video = new Entities\Video;

//由于它扩展了Entities\Product,您可以设置公共的产品属性
$ video-> setDescription('This is a Metallica clip');
$ video-> setPrice(19.95);

//设置自定义视频属性
$ artist = $ this-> doctrine-> em-> getRepository('Entities\Artist') - > findOneBy(array ('name'=>'Metallica'));
$ video-> setArtist($ artist);
$ video-> setReleaseDate(new DateTime());
$ video-> setFileName('metallica.mp4');

//保存
$ this-> doctrine-> em-> persist($ video);
$ this-> doctrine-> em-> flush();
}

public function createCar()
{
//实例化新的Entities\Car对象
$ car = new Entities\Car;

//由于它扩展了Entities\Product,您可以设置常用的产品属性
$ car-> setDescription('这是2011年福特Mondeo);
$ car-> setPrice(19.95);

//设置自定义Car属性
$ brand = $ this-> doctrine-> em-> getRepository('Entities\Brand') - > findOneBy(array ('name'=>'Ford'));
$ car-> setBrand($ brand);
$ car-> setReleaseDate(DateTime :: createFromFormat('Y-m-d','2011-11-15'));
$ car-> setModel('Mondeo');

//保存
$ this-> doctrine-> em-> persist($ car);
$ this-> doctrine-> em-> flush();
}



4)提取所有产品



关于如何提取所有产品的示例





  public function extractAllProducts ()
{
$ products = $ this-> doctrine-> em-> getRepository('Entities\Product') - > findAll();
foreach($ products as $ product)
{
printf('%s for€%s< br />',$ product-> getDescription(),$ product-> ;用getPrice());
}
}

这将导致

 这是€19.95 
的Metallica剪辑这是2011年的福特蒙迪欧€19.95

如何提取所有视频的示例

  public function extractAllVideos()
{
$ videos = $ this-> doctrine-> em-> getRepository('Entities\Video') - > findAll();
foreach($ videos as $ video)
{
printf('%s,已发布%s for€%s< br />',$ video-> getDescription() $ video-> getReleaseDate() - > format('Y'),$ video-> getPrice());
}
}

这将导致

 这是一个Metallica剪辑,2012年发售€19.95 


I'm using Doctrine 2.2.0 together with Codeigniter. I'm new to Doctrine (or to ORM in general).

I'm setting up entity and proxy classes based on YAML files which works fine. I do have problems in reflecting a polymorphic association in my DB in my Doctrine classes. I'm looking for a concrete example on how to implement the following polymorphic association in Doctrine.

In my DB I have a table called products. Depending on the value of field object_type and object_id I want to relate either to a record in the table videos or the table cars (I simplified it here). I want to keep both product types in 2 separate table because one has nothing to do with the other and both tables relate to other tables.

I took a look at the Doctrine Inheritance documentation and other examples, but it doesn't seem to help me. If possible I want to avoid adding the columns description and price to the tables videos and cars.

Many thanks!

|Table: products                                      |
|-----------------------------------------------------|
| ID | description | price  | object_type | object_id |
|-----------------------------------------------------|
| 1  | A video     | 20.00  | video       | 12        |
| 2  | A car       | 159.00 | car         | 5         |

|Table: videos                               |
|--------------------------------------------|
| ID | filename     | artist_id | date       |
|--------------------------------------------|
| 12 | somename.mp4 | 189       | 2011-02-15 |

|Table: cars                   |
|------------------------------|
| ID | brand_id | model | year |
|------------------------------|
| 5  | 17       | astra | 2010 |

解决方案

Found the solution myself. I've listed below the different steps I've done. This answer is very big, but I tried to be as complete as possible.

The most important things are in the Product YAML files inheritanceType: JOINED, discriminatorColumn:, discriminatorMap: and the Video and Car entity classes class Video extends Product, class Car extends Product.

1) DB Schema

CREATE TABLE IF NOT EXISTS `artists` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS `brands` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS `cars` (
  `id` int(11) NOT NULL,
  `model` varchar(255) NOT NULL,
  `release_date` date NOT NULL,
  `brand_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `description` varchar(255) NOT NULL,
  `price` double NOT NULL,
  `object_type` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS `videos` (
  `id` int(11) NOT NULL,
  `file_name` varchar(255) NOT NULL,
  `release_date` date NOT NULL,
  `artist_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

2) Doctrine YAML files (from which you need to create the Entity and proxy classes)

Entities.Artist.dcm.yml

Entities\Artist:
    type: entity
    table: artists
    id:
        id:
            type: integer
            primary: true
            notnull: true
            generator:
                strategy: AUTO
    fields:
        name:
            type: string(255)
            notnull: true
    oneToMany:
        videos:
            targetEntity: Video
            mappedBy: artist
    options:
        charset: utf8
        type: InnoDB

Entities.Brand.dcm.yml

Entities\Brand:
    type: entity
    table: brands
    id:
        id:
            type: integer
            primary: true
            notnull: true
            generator:
                strategy: AUTO
    fields:
        name:
            type: string(255)
            notnull: true
    oneToMany:
        cars:
            targetEntity: Car
            mappedBy: brand
    options:
        charset: utf8
        type: InnoDB

Entities.Car.dcm.yml

Entities\Car:
    type: entity
    table: cars
    fields:
        model:
            type: string
            notnull: true
        release_date:
            type: date
            notnull: true
    oneToOne: #unidirectional    
        brand:
            targetEntity: Brand
            joinColumns:
                brand_id:
                    referencedColumnName: id
    options:
        charset: utf8
        type: InnoDB

Entities.Product.dcm.yml

Entities\Product:
    type: entity
    table: products
    id:
        id:
            type: string
            primary: true
            notnull: true
            generator:
                strategy: AUTO
    fields:
        description:
            type: string(255)
            notnull: true
        price:
            type: decimal
            notnull: true
    inheritanceType: JOINED
    discriminatorColumn:
        name: object_type
        type: string
        length: 255
    discriminatorMap:
        video: Video
        car: Car
    options:
        charset: utf8
        type: InnoDB

Entities.Video.dcm.yml

Entities\Video:
    type: entity
    table: videos
    fields:
        file_name:
            type: string
            notnull: true
        release_date:
            type: date
            notnull: true
    oneToOne: #unidirectional    
        artist:
            targetEntity: Artist
            joinColumns:
                artist_id:
                    referencedColumnName: id
    options:
        charset: utf8
        type: InnoDB

3) Create Entity and Proxy classes

I use CodeIgniter. I've used Joel Verhagen's excellent guide

!! It's important you extend Video and Car with Product - See below !!

This results in the following Entity classes

Artist.php

namespace Entities;

use Doctrine\ORM\Mapping as ORM;

/**
 * Entities\Artist
 *
 * @ORM\Table(name="artists")
 * @ORM\Entity
 */
class Artist
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string $name
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * @var \Doctrine\Common\Collections\ArrayCollection
     *
     * @ORM\OneToMany(targetEntity="Entities\Video", mappedBy="artist")
     */
    private $videos;

    public function __construct()
    {
        $this->videos = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Artist
     */
    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Add videos
     *
     * @param Entities\Video $videos
     */
    public function addVideo(\Entities\Video $videos)
    {
        $this->videos[] = $videos;
    }

    /**
     * Get videos
     *
     * @return Doctrine\Common\Collections\Collection 
     */
    public function getVideos()
    {
        return $this->videos;
    }
}

Brand.php

namespace Entities;

use Doctrine\ORM\Mapping as ORM;

/**
 * Entities\Brand
 *
 * @ORM\Table(name="brands")
 * @ORM\Entity
 */
class Brand
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string $name
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * @var \Doctrine\Common\Collections\ArrayCollection
     *
     * @ORM\OneToMany(targetEntity="Entities\Car", mappedBy="brand")
     */
    private $cars;

    public function __construct()
    {
        $this->cars = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Brand
     */
    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Add cars
     *
     * @param Entities\Car $cars
     */
    public function addCar(\Entities\Car $cars)
    {
        $this->cars[] = $cars;
    }

    /**
     * Get cars
     *
     * @return Doctrine\Common\Collections\Collection 
     */
    public function getCars()
    {
        return $this->cars;
    }
}

Car.php

namespace Entities;

use Doctrine\ORM\Mapping as ORM;

/**
 * Entities\Car
 *
 * @ORM\Table(name="cars")
 * @ORM\Entity
 */
class Car extends Product //Important that Car extends Product
{
    /**
     * @var string $model
     *
     * @ORM\Column(name="model", type="string")
     */
    private $model;

    /**
     * @var date $release_date
     *
     * @ORM\Column(name="release_date", type="date")
     */
    private $release_date;

    /**
     * @var Entities\Brand
     *
     * @ORM\OneToOne(targetEntity="Entities\Brand")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="brand_id", referencedColumnName="id", unique=true)
     * })
     */
    private $brand;


    /**
     * Set model
     *
     * @param string $model
     * @return Car
     */
    public function setModel($model)
    {
        $this->model = $model;
        return $this;
    }

    /**
     * Get model
     *
     * @return string 
     */
    public function getModel()
    {
        return $this->model;
    }

    /**
     * Set release_date
     *
     * @param date $releaseDate
     * @return Car
     */
    public function setReleaseDate($releaseDate)
    {
        $this->release_date = $releaseDate;
        return $this;
    }

    /**
     * Get release_date
     *
     * @return date 
     */
    public function getReleaseDate()
    {
        return $this->release_date;
    }

    /**
     * Set brand
     *
     * @param Entities\Brand $brand
     * @return Car
     */
    public function setBrand(\Entities\Brand $brand = null)
    {
        $this->brand = $brand;
        return $this;
    }

    /**
     * Get brand
     *
     * @return Entities\Brand 
     */
    public function getBrand()
    {
        return $this->brand;
    }
}

Product.php

namespace Entities;

use Doctrine\ORM\Mapping as ORM;

/**
 * Entities\Product
 *
 * @ORM\Table(name="products")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="", type="", length=)
 * @ORM\DiscriminatorMap({"video" = "Entities\Video", "car" = "Entities\Car"})
 * @ORM\Entity
 */
class Product
{
    /**
     * @var string $id
     *
     * @ORM\Column(name="id", type="string")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string $description
     *
     * @ORM\Column(name="description", type="string", length=255)
     */
    private $description;

    /**
     * @var decimal $price
     *
     * @ORM\Column(name="price", type="decimal")
     */
    private $price;


    /**
     * Get id
     *
     * @return string 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set description
     *
     * @param string $description
     * @return Product
     */
    public function setDescription($description)
    {
        $this->description = $description;
        return $this;
    }

    /**
     * Get description
     *
     * @return string 
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * Set price
     *
     * @param decimal $price
     * @return Product
     */
    public function setPrice($price)
    {
        $this->price = $price;
        return $this;
    }

    /**
     * Get price
     *
     * @return decimal 
     */
    public function getPrice()
    {
        return $this->price;
    }
}

Video.php

namespace Entities;

use Doctrine\ORM\Mapping as ORM;

/**
 * Entities\Video
 *
 * @ORM\Table(name="videos")
 * @ORM\Entity
 */
class Video extends Product //Important that Video extends Product
{
    /**
     * @var string $file_name
     *
     * @ORM\Column(name="file_name", type="string")
     */
    private $file_name;

    /**
     * @var date $release_date
     *
     * @ORM\Column(name="release_date", type="date")
     */
    private $release_date;

    /**
     * @var Entities\Artist
     *
     * @ORM\OneToOne(targetEntity="Entities\Artist")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="artist_id", referencedColumnName="id", unique=true)
     * })
     */
    private $artist;


    /**
     * Set file_name
     *
     * @param string $fileName
     * @return Video
     */
    public function setFileName($fileName)
    {
        $this->file_name = $fileName;
        return $this;
    }

    /**
     * Get file_name
     *
     * @return string 
     */
    public function getFileName()
    {
        return $this->file_name;
    }

    /**
     * Set release_date
     *
     * @param date $releaseDate
     * @return Video
     */
    public function setReleaseDate($releaseDate)
    {
        $this->release_date = $releaseDate;
        return $this;
    }

    /**
     * Get release_date
     *
     * @return date 
     */
    public function getReleaseDate()
    {
        return $this->release_date;
    }

    /**
     * Set artist
     *
     * @param Entities\Artist $artist
     * @return Video
     */
    public function setArtist(\Entities\Artist $artist = null)
    {
        $this->artist = $artist;
        return $this;
    }

    /**
     * Get artist
     *
     * @return Entities\Artist 
     */
    public function getArtist()
    {
        return $this->artist;
    }
}

3) Creating a new Car and a new Video

This is what goes in my CodeIgniter controller. The code presumes you've created an artist with the name Metallica and a brand with the name Ford.

public function createVideo()
{
    //Instantiate new Entities\Video object
    $video = new Entities\Video;

    //Since it extends Entities\Product you can set the common Product properties
    $video->setDescription('This is a Metallica clip');
    $video->setPrice(19.95);

    //Setting the custom Video properties
    $artist = $this->doctrine->em->getRepository('Entities\Artist')->findOneBy(array('name' => 'Metallica'));
    $video->setArtist($artist);
    $video->setReleaseDate(new DateTime());
    $video->setFileName('metallica.mp4');

    //Save
    $this->doctrine->em->persist($video);
    $this->doctrine->em->flush();
}

public function createCar()
{
    //Instantiate new Entities\Car object
    $car = new Entities\Car;

    //Since it extends Entities\Product you can set the common Product properties
    $car->setDescription('This is Ford Mondeo of 2011');
    $car->setPrice(19.95);

    //Setting the custom Car properties
    $brand = $this->doctrine->em->getRepository('Entities\Brand')->findOneBy(array('name' => 'Ford'));
    $car->setBrand($brand);
    $car->setReleaseDate(DateTime::createFromFormat('Y-m-d', '2011-11-15'));
    $car->setModel('Mondeo');

    //Save
    $this->doctrine->em->persist($car);
    $this->doctrine->em->flush();
}

4) Extracting all products

An example on how to extract all Products

public function extractAllProducts()
{
    $products = $this->doctrine->em->getRepository('Entities\Product')->findAll();
    foreach($products as $product)
    {
        printf('%s for € %s<br />', $product->getDescription(), $product->getPrice());
    }
}

This results into

This is a Metallica clip for € 19.95
This is Ford Mondeo of 2011 for € 19.95

An example onn how to extract all Videos

public function extractAllVideos()
{
    $videos = $this->doctrine->em->getRepository('Entities\Video')->findAll();
    foreach($videos as $video)
    {
        printf('%s, released %s for € %s<br />', $video->getDescription(),  $video->getReleaseDate()->format('Y'), $video->getPrice());
    }
}

This results into

This is a Metallica clip, released 2012 for € 19.95

这篇关于反映了Doctrine 2.2中的MySQL多态关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆