Как определить Doctrine mappedSuperclass, используя XML или YAML вместо отображения аннотаций - PullRequest
0 голосов
/ 05 февраля 2019

Следующий скрипт взят из https://www.doctrine -project.org / projects / doctrine-orm / en / 2.6 / reference / inheritance-mapping.html # mapped-superclasses и был изменен только для включениявторой подкласс.Насколько я понимаю, MappedSuperclassBase не может существовать сам по себе, но должен быть расширен одним и только одним подклассом (т. Е. EntitySubClassOne или EntitySubClassTwo), и это то же понятие, что и супертип / подтип для SQL.Согласитесь?

Как определяется супер / подтип с использованием YAML или XML вместо отображения аннотаций?

<?php
/** @MappedSuperclass */
class MappedSuperclassBase
{
    /** @Column(type="integer") */
    protected $mapped1;
    /** @Column(type="string") */
    protected $mapped2;
    /**
     * @OneToOne(targetEntity="MappedSuperclassRelated1")
     * @JoinColumn(name="related1_id", referencedColumnName="id")
     */
    protected $mappedRelated1;

    // ... more fields and methods
}

/** @Entity */
class EntitySubClassOne extends MappedSuperclassBase
{
    /** @Id @Column(type="integer") */
    private $id;
    /** @Column(type="string") */
    private $name;

    // ... more fields and methods
}

/** @Entity */
class EntitySubClassTwo extends MappedSuperclassBase
{
    /** @Id @Column(type="integer") */
    private $id;
    /** @Column(type="string") */
    private $name;

    // ... more fields and methods
}

1 Ответ

0 голосов
/ 06 февраля 2019

Судя по нашим комментариям, я вижу ваше замешательство.Поскольку документы обрабатывают как "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


Надеюсь, что удалосьчтобы очистить вещи для вас.Если нет, не стесняйтесь спрашивать.

...