在条令2中手动生成下一个序列值


Generating next sequence value manually in Doctrine 2

对于给定名称的特定序列,生成nextval的最简单方法是什么?

指定的注释解决方案

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

这并不能让我满意,只要涉及到一些更复杂的逻辑:在某些情况下,我需要检索nextval,在其他情况下——我会使用从另一个源(而不是序列)检索的值。

因此,我希望有一种方法可以在实体的构造函数中手动检索序列nextval。

万一有人提出这个问题(就像我一样):
Florian提到的拉拽请求现在已经成为一种学说。尽管文档似乎仍然缺乏CUSTOMid生成器策略的任何信息。在GeneratedValue描述中,我只找到了提到IdGenerator的CUSTOM选项的部分。如果我错过了,请在评论中纠正我。

它很难实现。只需创建一个扩展Doctrine'ORM'Id'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;

仅此而已;)

在Doctrine2:中有两种获得序列nextval的可能性

  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);
    

那么我认为您应该实现自己的Identitfer生成器。

最简单的方法是覆盖Doctrine''ORM''Id''SequenceGenerator类来处理您的特定情况。

然后,您必须使用Doctrine ORM API在类元数据中注册此生成器。

一些链接: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

我有symfony 6和条令orm 2.13,可以使用代码,在SomeEntityRepository中创建的函数:

public function fetchSeqId(EntityManagerInterface $entityManager){
    $dbConnection = $entityManager->getConnection();
    $nextValQuery = $dbConnection->getDatabasePlatform()->getSequenceNextValSQL('some_id_seq');        
    $id = (int) $dbConnection->executeQuery($nextValQuery)->fetchOne();
    return $id;
}

并在控制器中用作:

$repository = $this->entityManager->getRepository(SomeEntity::class);
$id= $repository->fetchSeqId($this->entityManager);