Inheritance Symfony2原则声明实体以使用单独的DB表维护继承
我正在写一个程序来跟踪客户可以订购的帆船。 我的程序具有以下类结构:Inheritance Symfony2原则声明实体以使用单独的DB表维护继承,inheritance,symfony,doctrine,Inheritance,Symfony,Doctrine,我正在写一个程序来跟踪客户可以订购的帆船。 我的程序具有以下类结构: Sail - mainsail - jib - spinnaker 我不确定是否使用mappedsuperclass或其他一些条令继承类型来维护程序内的以下类型的关系: Mainsail extends Sail 我希望数据库本身(mySQL)分别有一个mainsail、jib和spinnaker表 到目前为止,我的Co/QuoteBundle/entity文件夹中只有一个Mainsail实体/类:
Sail
- mainsail
- jib
- spinnaker
我不确定是否使用mappedsuperclass或其他一些条令继承类型来维护程序内的以下类型的关系:
Mainsail extends Sail
我希望数据库本身(mySQL)分别有一个mainsail、jib和spinnaker表
到目前为止,我的Co/QuoteBundle/entity文件夹中只有一个Mainsail实体/类:
namespace Co\QuoteBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Mainsail
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Co\QuoteBundle\Entity\MainsailRepository")
*/
class Mainsail
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=100)
*/
private $name;
/**
* @var integer
*
* @ORM\ManyToOne(targetEntity="Boat", inversedBy="mainsails")
* @ORM\JoinColumn(name="boat_id", referencedColumnName="id")
* @Assert\NotBlank()
*/
private $boatType;
/**
* @var float
*
* @ORM\Column(name="build_price", type="decimal")
*/
private $buildPrice;
//other variables, plus doctrine-generated getters and setters
}
最终,我的目标是不必为所有的sail类复制相同的功能,这样我就可以将sail阵列发送到twig中,并在适用的情况下将它们视为相同类型或不同类型
{% for sail in sails %}
<p>{{sail.name}} (${{sail.buildPrice}})</p>
{% endfor %}
{%用于帆中帆%}
{{sail.name}(${sail.buildPrice}})
{%endfor%}
谢谢 如果希望每个表共享公共属性,则类表继承是最佳选择:
这实际上取决于不同类型的帆之间有多少差异。如果只是几个属性,那么单表继承速度更快,可能适合您的需要。仔细阅读有关继承的章节。根据@Cerad的回答,我提出了以下DB模式:
sail {id (int), boat_id (int), discr (varchar), options (bool)}
mainsail {id (int), name (varchar), build_price (decimal), weight_lbs (decimal)}
jib {id (int), name (varchar), build_price (decimal), weight_lbs (decimal)}
spinnaker {id (int), name (varchar), build_price (decimal), weight_lbs (decimal)}
这是通过运行
$php app/console doctrine:generate:entities {packagename}
$php app/console doctrine:schema:update --force
关闭以下代码:
(条令从注释中生成discr列)
帆船级别:
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity(repositoryClass="Co\QuoteBundle\Entity\SailRepository")
* @ORM\Table(name="sail")
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"main" = "Mainsail", "jib" = "Jib", "genoa" = "Genoa", "spinnaker" = "Spinnaker"})
*/
class Sail {
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var integer
*
* @ORM\ManyToOne(targetEntity="Boat", inversedBy="sails")
* @ORM\JoinColumn(name="boat_id", referencedColumnName="id", nullable=false)
* @Assert\NotBlank()
*/
private $boatType;
/**
* @var boolean
*
* @ORM\Column(name="options", type="boolean")
*/
private $hasOptions;
/**
* @ORM\OneToMany(targetEntity="SailOption", mappedBy="owningSail")
*/
private $optionChoices;
//setters and getters generated by doctrine
主帆等级(三角帆和三角帆相同):
是的,名称、构建价格和权重变量中存在冗余。我把它们放在单独的表格中,因为我觉得这是一种更好的方法,可以在将来开发一个简单的CMS,单独添加/删除帆。因为我还没有解决这个问题,而且我对这个问题还比较陌生,所以我不确定情况是否会是这样。欢迎评论:)
谢谢 据我所知,这会给数据库本身添加一个额外的表吗?前几天我所做的只是创建一个抽象类,其中每个继承类的getter和setter定义为abstract。因此,我有抽象类AbstractSail,像Mainsail这样的类扩展了AbstractSail。这仍然需要我将私有变量从一个类复制到另一个类,但它保证每个继承类中至少有相同的getter和setter。这个策略有效吗?回答我自己的问题,这不会添加额外的表。由多对多继承通过
@JoinTable
注释创建的。我最终没有将类抽象化,因为它不会以这种方式显示在数据库中,而且我也不能有一个中央数据库表来存储boat-sail关系,这正是sail
表的主要用途。我把这个作为答案,因为它给了我一个良好的开端。我在下面列出了我的完整解决方案。谢谢@Cerad
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Mainsail
*
* @ORM\Table(name="mainsail")
* @ORM\Entity(repositoryClass="Co\QuoteBundle\Entity\MainsailRepository")
*/
class Mainsail extends Sail {
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=100)
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="descr", type="string", length=255, nullable=true)
*/
private $descr;
/**
* @var float
*
* @ORM\Column(name="build_price", type="decimal", precision=7, scale=2)
*/
private $buildPrice;
/**
* @var float
*
* @ORM\Column(name="weight_lbs", type="decimal", precision=4, scale=1)
*/
private $weightLbs;
//getters and setters generated by doctrine