Генерация следующего значения последовательности вручную в Доктрине 2


Какой был бы самый простой способ сгенерировать nextval для некоторой конкретной последовательности с заданным именем?

Решение аннотации с указанием

 * @ORM\GeneratedValue(strategy="SEQUENCE")
 * @ORM\SequenceGenerator(sequenceName="sq_foobar", allocationSize="1", initialValue="1")

Меня не удовлетворяет, пока задействована более сложная логика: в некоторых случаях мне нужно получить nextval, в других - я бы использовал значение, полученное из других источников (не последовательность).

Поэтому я надеюсь, что есть способ получить последовательность nextval вручную в конструкторе сущности.

Author: Benjamin, 2012-02-01

3 answers

Тогда, я думаю, вам следует реализовать свой собственный генератор идентификаторов.

Проще всего было бы переопределить класс Doctrine\ORM\Id\SequenceGenerator для обработки вашего конкретного случая.

Затем вам необходимо зарегистрировать этот генератор в метаданных класса с помощью API Doctrine ORM.

Некоторые ссылки: http://ranskills.wordpress.com/2011/05/26/how-to-add-a-custom-id-generation-strategy-to-doctrine-2-1/

Https://github.com/doctrine/doctrine2/pull/206

 4
Author: Florian, 2012-02-03 14:12:11

На всякий случай, если кто-то другой ответит на этот вопрос (как это сделал я):
Запрос на вытягивание, о котором упоминал Флориан, теперь превратился в доктрину. Хотя в документации, похоже, по-прежнему отсутствует какая-либо информация о стратегии ПОЛЬЗОВАТЕЛЬСКОГО генератора идентификаторов. Только часть, которую я нашел, где упоминается опция CUSTOM для IdGenerator, находится в описании GeneratedValue. Если я пропустил это, пожалуйста, исправьте меня в комментариях.

Это может быть легко реализовано. Просто создайте класс, расширяющий Doctrine\ORM\Id\AbstractIdGenerator\AbstractIdGenerator:

namespace My\Namespace;
use Doctrine\ORM\Id\AbstractIdGenerator;
class MyIdGenerator extends AbstractIdGenerator
{
    public function generate(\Doctrine\ORM\EntityManager $em, $entity)
    {
        // Create id here
        $id = <do some logic>;
        return $id;
    }
}

Затем добавьте его в свое описание id в конфигурации сущности доктрины (пример YAML):

My\Bundle\Entity\MyEntity:
    type: entity
    id:
        id:
            type: bigint
            unique: true
            generator:
                strategy: CUSTOM
            customIdGenerator:
                class: 'My\Namespace\MyIdGenerator'
    fields:
        otherField: .... 

Если вы используете Annotations вместо YAML, конфигурация сущности должна выглядеть так (непроверенная):

/**
  * @Id 
  * @Column(type="integer")
  * @GeneratedValue(strategy="CUSTOM")
  * @CustomIdGenerator(class="My\Namespace\MyIdGenerator")
  */
  public $id;

И это все;)

 37
Author: enricog, 2018-09-17 21:48:37

Есть две возможности получить последовательность nextval в Доктрине2:

  1. Используйте генератор последовательности ORM доктрины

    use Doctrine\ORM\Id\SequenceGenerator;
    $sequenceName = 'file_id_seq';
    $sequenceGenerator = new SequenceGenerator($sequenceName, 1);
    $newId = $sequenceGenerator->generate($entityManager, $entity);
    // $entity in this case is actually not used in generate() method, so you can give any empty object, or if you are not worried about editor/IDE warnings, you can also specify null
    
  2. Используйте собственный SQL

    $sequenceName = 'file_id_seq';
    $dbConnection = $entityManager->getConnection();
    $nextvalQuery = $dbConnection->getDatabasePlatform()->getSequenceNextValSQL($sequenceName);
    // $nextvalQuery is now following string "SELECT NEXTVAL('file_id_seq')"
    $newId = (int)$dbConnection->fetchColumn($nextvalQuery);
    
 18
Author: darklow, 2012-07-17 11:35:17