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