2012-01-31 46 views
12

对于给定名称的某些特定序列,生成nextval最简单的方法是什么?在Doctrine 2中手动生成下一个序列值

与指定

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

不能满足我,只要有一些涉及到更复杂的逻辑批注解决方案:在某些情况下,我需要检索nextval,在其他 - 我会去的从其他来源(不是序列)检索到的值。

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

回答

4

然后我认为你应该实现你自己的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

+4

该文章建议修改核心文件:-S – zerkms 2012-02-03 20:26:12

+0

是的。如果不修改核心原则文件,这是不可能的,直到合并PR#206。 – Florian 2012-02-04 13:08:44

+0

即使这不是一个好主意,你仍然可以维护自己的分支。但更糟糕的想法是混合标识符生成。 – Florian 2012-02-04 13:14:12

16

有两种可能性越来越序列NEXTVAL在Doctrine2:

  1. 使用原则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); 
    
+0

我现在不记得 - 但由于某些原因,这些明显的解决方案不符合我的要求,但它太早了,所以+1 time ;-) – zerkms 2012-07-17 11:37:40

+0

对于非pk列只有第二个变体是解决方案 – timaschew 2012-11-27 07:57:27

+0

如果您使用allocationSize> 1,例如:allocationSize =“100”,则第二种解决方案将无法正常工作,因为它每次都会跳100个值。 – ChocoDeveloper 2013-08-13 00:03:48

36

就在对这个问题的情况下,别人的土地(像我一样):
拉入请求@Florian提到的把它做成主义了。虽然文档似乎仍然缺乏任何关于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; 

这就是所有;)