Судя по нашим комментариям, я вижу ваше замешательство.Поскольку документы обрабатывают как "MappedSuperclass", так и "Discriminator" на одной странице, я думаю, вы перепутали их использование в своей голове.Надеюсь, это поможет вам:
- A
MappedSuperclass
предоставляет свойства / значения по умолчанию для повторного использования, но оно никогда не может быть сущностью само по себе.Это сопоставимо с классами PHP abstract
(которые не могут быть созданы сами по себе) - Дискриминатор предоставляет возможность «расширять» сущность, делая ее другой сущностью.Например, наличие
Person
сущности дает вам 1 сущность.Эта сущность может быть расширена, например, на Worker
и Manager
.
. Хорошим вариантом использования для MappedSuperclass
будет AbstractEntity
.Каждому субъекту нужен идентификатор, уникальный идентификатор.Это также дает вам что-то общее для проверки в Слушателях и тому подобное.Итак, продолжайте и создайте:
/**
* @ORM\MappedSuperclass
*/
abstract class AbstractEntity
{
/**
* @var int
* @ORM\Id
* @ORM\Column(name="id", type="integer", options={"unsigned":true})
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
// getter / setter
}
Посмотрите, как это объявляется abstract
и MappedSuperclass
?
Это потому, что ни один (abstract class
и MappedSuperclass
) не может быть создан самостоятельно.Вы не можете сделать $entity = new AbstractEntity()
, потому что это abstract
класс PHP.Doctrine также не создаст отдельную таблицу для AbstractEntity
.
Далее создайте Person
:
/**
* @ORM\Entity
* @ORM\Table(name="persons")
*
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
*/
class Person extends AbstractEntity
{
/**
* @var string
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
protected $name;
// getter / setter
}
Выше, Person
, Entity настроен на Наследование таблиц классов через JOINED
тип наследования,Это означает, что на уровне базы данных таблица persons
будет отделена от любых столбцов, добавленных другими объектами, с расширением Person
.
Обратите внимание, как я не объявил DiscriminatorMap
.Ниже из документов, выделенных мной жирным шрифтом:
На заметку:
- @InheritanceType, @DiscriminatorColumn и @DiscriminatorMap должны быть указаны в самом верхнем классе, которыйявляется частью иерархии сопоставленных сущностей.
- @DiscriminatorMap указывает, какие значения столбца дискриминатора определяют строку как принадлежащую к какому типу.В приведенном выше случае значение «person» идентифицирует строку как тип Person, а «employee» определяет строку как тип Employee.
- Имена классов в карте дискриминатора не должныбыть полностью квалифицированным, если классы содержатся в том же пространстве имен, что и класс сущностей, к которому применяется карта дискриминатора.
- Если карта дискриминатора не предоставлена, карта генерируется автоматически .Автоматически сгенерированная карта дискриминатора содержит в качестве ключа короткое имя каждого класса в нижнем регистре.
Теперь давайте создадим Worker
:
/**
* @ORM\Entity
* @ORM\Table(name="workers")
*/
class Worker extends Person
{
/**
* @var int
* @ORM\Column(name="worker_id", type="integer", length=11, nullable=false)
*/
protected $workerId;
// getter / setter
}
Итак, теперь мыУ вас есть:
- MappedSuperclass:
AbstractEntity
- это не автономный объект - Дискриминация:
Person
- это отдельная сущность - "нормальный":
Worker
- расширяется Person
Примечания:
- MappedSuperclass не может быть может быть создан.Таким образом: вы не можете создавать ссылки / отношения к нему.Сравним с PHP
abstract class
- Дискриминационным объектом является тот, который также является отдельным и может использоваться как обычный объект.Вы можете создавать отношения с ним и без него
- Сущность, расширяющая дискриминируемую сущность, является примером того и другого.В приведенном выше коде они оба истинны:
$worker instanceof Worker
и $worker instanceof Person
, потому что Worker
расширяет Person
.Однако, $person instanceof Worker
будет false
!
$workerId = $person->getWorkerId() // generates "method does not exist" fatal
$workerId = $worker->getWorkerId() // generates integer value
Надеюсь, что удалосьчтобы очистить вещи для вас.Если нет, не стесняйтесь спрашивать.