我已阅读Doctrine 2 Inheritance Mapping with Association但请说明您是否需要Animal
作为一个实体,比如创建选项列表。
在这种情况下,Pet
的判别列位于animal table
的种类列中。
所以课程就是这样的。
class Animal
{
$id;
$species;
}
/**
* @Table(name="animal")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="species", type="string")
* @DiscriminatorMap({"dog" = "Dog", "cat" = "Cat"})
*/
abstract class Pet
{
$id
$species;
}
class Dog extends Pet { }
class Cat extends Pet { }
class Owner
{
/**
* @OneToMany(targetEntity="Pet")
*/
$pets
}
我看到了一些问题。
animal
表没有owner
的外键。所以
$pets
关联不起作用。
Animal
和Pet
或多或少都是一样的。如果有的话
更改Animal
中的内容,这些更改不会反映在其中
任何Pet
子类。
第一个问题的一个可能的解决方案是有一个名为pet
的额外表,但关联仍然存在问题,因为鉴别器列仍然在animal
表中并且重复pet
中的列会破坏规范化。
答案 0 :(得分:3)
我不确定完全理解你的问题,但我会试一试:
Pet
为Animal
,在您的类层次结构中明确显示是有意义的。请注意, abstract 类Pet
可以继承具体类Animal
。这样,您仍然可以实例化Animal
,Dog
或Cat
,但无法实例化Pet
; Animal
根类可以具有自己的鉴别器值,这样可以使用Doctrine持久化它。然后,您可以创建并保留Dog
或Cat
,甚至是通用Animal
; Animal
需要对其所有者的引用; Owner
现在与Animal
之间存在一对多关系; species
列是一个鉴别器,并且没有值添加到您的域模型(类名称会告诉您正在处理的Animal
,所以我建议删除这个属性。最后说明,你真的需要一个Pet
课吗?如果一个宠物没有特定的Animal
(即该类是空的),那么你应该从你的类层次结构中删除它。
class Owner {
/**
* @OneToMany(targetEntity="Animal")
*/
protected $animals;
}
/**
* @Table(name="animal")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="species", type="string")
* @DiscriminatorMap({"animal" = "Animal", "dog" = "Dog", "cat" = "Cat"})
*/
class Animal {
/** @Id @Column(type="integer") @GeneratedValue */
protected $id;
/** @ManyToOne(targetEntity="Owner") */
protected $owner;
}
abstract class Pet extends Animal {
// Do you really need this class?
}
class Dog extends Pet {
// ...
}
class Cat extends Pet {
// ...
}
关于您的数据库结构,我建议进行以下更改:
owner_id
&移动Dog
Cat
表格Animal
; animal_id
&中删除Dog
Cat
个表格;他们将与id
表(一对一)共享Animal
值。