2012-01-31 53 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; 

這就是所有;)