gpt4 book ai didi

doctrine-orm - 在 Doctrine 2.2 中反射(reflect) MySQL 多态关联

转载 作者:行者123 更新时间:2023-12-04 18:24:05 25 4
gpt4 key购买 nike

我将 Doctrine 2.2.0 与 Codeigniter 一起使用。我是 Doctrine 的新手(或者一般来说是 ORM 的新手)。

我正在基于 YAML 文件设置实体和代理类,效果很好。我在我的 Doctrine 类中反射(reflect)我的数据库中的多态关联时确实存在问题。我正在寻找一个关于如何在 Doctrine 中实现以下多态关联的具体示例。

在我的数据库中,我有一个名为 products 的表。取决于字段 object_type 的值和 object_id我想与桌面视频或桌面汽车中的记录相关(我在这里简化了它)。我想将两种产品类型保留在 2 个单独的表中,因为一个与另一个无关,并且两个表都与其他表相关。

我查看了 Doctrine Inheritance 文档和其他示例,但它似乎对我没有帮助。 如果可能,我想避免添加列 descriptionprice到表视频和汽车 .

非常感谢!

|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 |

最佳答案

自己找到了解决方案。我在下面列出了我已完成的不同步骤。这个答案很大,但我尽量做到完整。

最重要的内容在产品 YAML 文件中 inheritanceType: JOINED , discriminatorColumn: , discriminatorMap:以及视频和汽车实体类 class Video extends Product , class Car extends Product .

1) 数据库模式

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 文件(您需要从中创建实体和代理类)

Entity.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

Entity.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

实体.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

实体.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

Entity.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) 创建实体和代理类

我使用 CodeIgniter。 I've used Joel Verhagen's excellent guide

!!使用产品扩展视频和汽车很重要 - 见下文!

这导致以下实体类

艺术家.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;
}
}

品牌.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;
}
}

汽车.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;
}
}

产品.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;
}
}

视频.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) 创建新汽车和新视频

这就是我的 CodeIgniter Controller 中的内容。该代码假定您创建了一个名为 Metallica 的艺术家和一个名为 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)提取所有产品

关于如何提取所有产品的示例
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 is a Metallica clip for € 19.95
This is Ford Mondeo of 2011 for € 19.95

如何提取所有视频的示例
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 is a Metallica clip, released 2012 for € 19.95

关于doctrine-orm - 在 Doctrine 2.2 中反射(reflect) MySQL 多态关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10079897/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com