php - Doctrine 2 具体表继承与关联

标签 php inheritance orm doctrine-orm concrete-inheritance

我已阅读 Doctrine 2 Inheritance Mapping with Association但是说如果你需要 Animal 本身就是一个实体,比如创建选项列表。

在这种情况下,Pet 的鉴别器列位于 animal 表 的物种列中。

Pet Database Schema

所以类应该是这样的。

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
}

我看到了几个问题。

  1. animal 表没有指向 owner 的外键。所以 $pets 关联将不起作用。

  2. AnimalPet 或多或少是同一件事。如果有人 更改 Animal 中的某些内容,这些更改不会反射(reflect)在 任何 Pet 子类。

第一个问题的可能解决方案是有一个名为pet 的额外表,但是关联仍然存在问题,因为鉴别器列仍在animal 表并复制 pet 中的列会破坏规范化。

enter image description here

最佳答案

我不确定是否完全理解您的问题,但我会试一试:

  • Pet 是一种Animal在您的类层次结构中使其显式显示 是有意义的。请注意,抽象Pet 可以子类化 具体Animal。这样,您仍然可以实例化 AnimalDogCat,但不能实例化 Pet;
  • Animal 根类可以有自己的鉴别器值,这使得用 Doctrine 持久化它成为可能。然后,您可以创建并保留 DogCat,甚至是通用的 Animal
  • Animal 需要对其所有者的引用
  • Owner 现在与 Animal 具有一对多关系
  • species 列是一个鉴别器,不会为您的域模型添加任何值(类名会告诉您您是哪种Animal正在处理),所以我建议删除此属性。

最后一点,你真的需要一个Pet类吗?如果 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_idDogCat 移动到 Animal 表;
  • DogCat 表中删除 animal_id;它们将与 Animal 表共享 id 值(一对一)。

关于php - Doctrine 2 具体表继承与关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8267500/

相关文章:

PHP PCNTL - pcntl_signal() 的 restart_syscalls 参数有什么作用?

C++ - 希望虚拟仅作为重定向

sql - Eloquent ORM 交叉搜索

java - 如何在 JPA 和 Hibernate 中从具有大量子项的 @ManyToMany 关系中删除子对象

hibernate - ColdFusion 9 ORM 关系映射

PHP - 清理垃圾

php - 需要 PHP 帮助 : Trying to Pull MySQL Data From Record Matching Variable. 变量由 If-Then 语句设置。部分有效

php - PHP 7.0.11 中的 BUG,FILTER_FLAG_NO_RES_RANGE

c++从不变函数返回时断言失败

javascript - Controller 继承在 AngularJS 中是一个好的实践吗?