2012-01-06 118 views
7

使用doctrine,symfony2更新數據庫中的多個記錄的最佳方法是什麼?Symfony - 更新多個記錄

我收到了必須更新的記錄ID數組。
我想分配給每個記錄其索引從接收數組到列show_order。 所以,如果我收到數組$陣列=陣列(22,1,5,10),那麼我想這樣做

$i = 0; 
foreach($array as $a) { 
    $record = $this->getDoctrine->getRepository('AcmeBundle:SomeEntity')->findOneById($a); 
    if ($record != null) $record->setOrder($i++); 
} 
$this->getDoctrine()->getEntityManager()->flush(); 

但它是可怕的方式,因爲每個記錄我做一個選擇,所以查詢的號碼是上)。

如何做得更好?

+0

我有現在一個想法:把所有的記錄,檢查哪個順序發生了變化,只對其進行更新。但是,由於這種解決方案,我感到不滿意。所以它會做一個SELECT來獲取所有記錄,很少選擇(獲取實體對象)和少許更新(或者可能只有一個,因爲我認爲在flush()之後調用更新)。 – 2012-01-06 22:40:37

+0

如果使用doctrine2沒有好的解決方案,也許我應該在清晰的PHP中執行,並使用CASE WHEN ... THEN ...在SQL查詢中? – 2012-01-07 00:58:01

回答

6

喜歡的東西...

foreach ($repo->findById($ids) as $obj) { 
    $obj->setOrder(array_search($obj->getId(), $ids)); 
} 

$em->flush(); 
+0

對我來說似乎很好 - 一個選擇,一個更新。我完全忘了我可以將數組作爲參數傳遞給findById。 :) – 2012-01-07 21:05:13

+3

我剛剛在我的symfony項目中實現了這個功能,並且通過觀看應用程序/ dev.log,它爲每個記錄進行一次選擇和更新 - 而不是一次更新 – semateos 2012-07-11 20:50:10

6

作爲第一個選項,您應該考慮Batch Processing。如果出於某種原因您不適合您,第二個選擇是使用純SQL,可能通過DBAL

+0

相當有用的東西,謝謝。 – 2012-01-07 21:05:26

0

所以這仍然是0(n)的,但它是1N而非2N。

namespace BRS\PageBundle\Repository; 

use Doctrine\ORM\EntityRepository; 

class ContentRepository extends EntityRepository 
{ 
    public function reorder($content) 
    {  
     $em = $this->getEntityManager(); 

     $count = 0; 

     foreach($content as $i => $content_id){ 

      $q = $em->createQuery('update BRSPageBundle:Content c set c.display_order = ?1 where c.id = ?2') 
        ->setParameter(1, $i) 
        ->setParameter(2, $content_id); 

      $count += $q->execute(); 
     } 

     return $count; 
    } 
} 

然後說你有內容ID陣列,以這樣的:

$content = array(23,12,8,4); 

然後爲了避免不必要的選擇,我使用custom repository class和學說查詢生成器,像這樣解決了這個問題你可以從你的控制器倒也乾脆更新的順序:

$count = $this->getRepository('BRSPageBundle:Content')->reorder($content);