2016-10-04 55 views
1

this old post反彈我正在尋找一種方法來更新一個SQL查詢中的幾個Symfony實體 - 爲了優化原因。我有一個Content實體和一個服務中的方法,它使用setCurrent(0)更新所有「同級」內容。這是迄今爲止的工作代碼:Symfony3 - 在單個SQL查詢中更新多個實體

/** 
* Set given content the latest regarding its siblings 
*/ 
public function setLatestContent(Entity\Content $content) 
{ 
    // Get siblings entities 
    $siblings = $this 
     ->em 
     ->getRepository('LPFrontRteBundle:Content') 
     ->findBySibling($content); 

    foreach ($siblings as $sibling_content) { 
     $sibling_content->setCurrent(0); 
    } 

    $this->em->flush(); 
} 

那麼工作。但因爲我有38頁同級的內容,我得到38個SQL查詢:

UPDATE mr_content SET current = 0 WHERE id = 55 
UPDATE mr_content SET current = 0 WHERE id = 56 
UPDATE mr_content SET current = 0 WHERE id = 57 
... 

我想用主義的「乾淨」的實體制度,辦法有一個查詢,如:

UPDATE mr_content SET current = 0 WHERE id = 55 OR id = 56 OR id = 57 ... 

任何想法如何實現這一點 - 或更聰明的解決方法,將不勝感激。


編輯

爲了記錄在案,這裏就是我想出了 - 我喜歡它冗長:) 隨着$ QB作爲查詢生成器。

$qb->update('LPFrontRteBundle:Content', 'c') 
     ->set('c.current', 0) 

     ->where('c.keyword = :keyword') 
     ->setParameter('keyword', $content->getKeyword()) 

     ->andWhere('c.locale = :locale') 
     ->setParameter('locale', $content->getLocale()) 

     ->andWhere('c.id != :id') 
     ->setParameter('id', $content->getId()) 

     ->getQuery()->execute(); 

回答

4

Batch processing更新所有實體是你在找什麼。

Doctrine2中有兩種批量更新方法。

第一個問題是DQL更新查詢,這對你來說可能是最好的。它會是這樣的:

$q = $em->createQuery("UPDATE LPFrontRteBundle:Content c SET c.current = 0 WHERE id IN (:ids)") 
     ->setParameter(':ids', $ids, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY)); 
$numUpdated = $q->execute(); 
+0

謝謝!我終於與一個非常接近的解決方案,我會發布,但這確實是我一直在尋找:) – LoicPenn

1

您可以收集所有的IDS和執行DQL一次

$ids = array(); 
foreach ($siblings as $sibling_content) { 
    $ids[] = $sibling_content->getId(); 
} 

$this->em->createQuery(" 
    UPDATE 
     LPFrontRteBundle:Content t 
    SET 
     t.current = 0 
    WHERE 
     t.id IN (:ids) 
") 
->setParameter(':ids', $ids, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY) 
->execute(); 
+0

謝謝!我所做的是跳過「實體提取」部分直接從查詢中更新。我閱讀Repos只是爲了「取材」的目的,但也許這只是一個哲學問題? – LoicPenn

+0

我認爲你是對的,而且有些服務更適用於這樣的操作。在我的項目中,爲了簡單起見,我在存儲庫中放置了這樣的操作:)我將刪除我的答案的第二部分,不要混淆其他用戶 –