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

时间:2012-01-31 21:58:40

标签: php doctrine-orm

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

指定

的注释解决方案
 * @ORM\GeneratedValue(strategy="SEQUENCE")
 * @ORM\SequenceGenerator(sequenceName="sq_foobar", allocationSize="1", initialValue="1")

不满足我,只要涉及更复杂的逻辑:在某些情况下我需要检索nextval,在其他情况下 - 我会使用从其他来源检索的值(不是序列)

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

3 个答案:

答案 0 :(得分:39)

以防万一其他人提出这个问题(就像我做的那样):
@Florian提到的拉动请求现在已经成为学说。虽然文档似乎仍然缺少 CUSTOM id生成器策略的任何信息。只有我发现提到IdGenerator的CUSTOM选项的部分是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;

这就是全部;)

答案 1 :(得分:19)

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

  1. 使用Doctrine ORM SequenceGenerator

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

答案 2 :(得分:3)

然后我认为你应该实现自己的Identitfer Generator。

最简单的方法是覆盖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