2015-02-23 70 views
6

我正在使用2.4教條的symfony 2.5項目。如何在Symfony 2.4中緩存doctrine「findOneBy()」查詢與緩存ID和緩存生存期選項?

我想緩存查詢結果與緩存ID和緩存時間,所以我可以刪除緩存結果,只要需要,雖然管理員。

我可以使用「createQueryBuilder()」選項緩存查詢結果。

例子:

$this->createQueryBuilder('some_table') 
        ->select('some_table') 
        ->where('some_table.deleted_date IS NULL') 
        ->getQuery() 
        ->useResultCache(true) 
        ->setResultCacheLifetime(120) //Query Cache lifetime 
        ->setResultCacheId($queryCacheId) //Query Cache Id 
        ->getResult(); 

但我沒能找到類似的方式chache爲 「findOneBy()」 選項查詢結果。

例子:

$this->findOneBy(array('some_field'=>$some_value)); 

我要尋找一些妥善的解決辦法,任何的幫助深表感謝。

+1

https://groups.google.com/d/msg/doctrine-user/RIeH8ZkKyEY/HnR7h2p0lCQJ 作爲Ocramius說,你NEDD重寫此方法爲回購協議,如果你想利用高速緩存操作的優勢。 – DonCallisto 2015-02-23 08:54:49

+0

感謝您的回覆。讓我試一下,如果需要的話,會問你更多。 – 2015-02-23 09:07:34

+0

這是我重寫 「findOneBy」 功能在存儲庫中的類 公共函數findOneBy(數組$ criteria_array) { \t \t $查詢= $這 - > createQueryBuilder( 'B') - >選擇( 'B'); \t \t的foreach($ criteria_array爲$的fieldName => $條件){ \t \t \t $查詢 - > andWhere( 「B $的fieldName =:$的fieldName」); \t \t \t $ query-> setParameter(「$ fieldName」,$ criteria); \t \t} \t \t回報$查詢 - > getQuery() \t \t \t - > useResultCache(真) \t \t \t - > setResultCacheLifetime(120) \t \t \t - > setResultCacheId($ queryCacheId) \t \t \t - >的getResult(); } 請檢查並更正我。 當我需要緩存結果時,是否需要覆蓋所有存儲庫中的「find *」函數? – 2015-02-23 10:08:10

回答

0

爲此做一個共同的功能。

$repo->findOneByYourSufff($yourStuff, $yourRepoClass); 

其次是你的常用功能:

public function findOneByYourSufff($yourStuff, $yourRepoClass) { 


     $q = $this->createQueryBuilder() 
       ->select('x.*') 
       ->from($yourRepoClass, 'x'); 

       foreach($yourStuff as $fieldKey => $wh) { 
        $q->andWhere("b.$fieldKey = :fieldName"); 
        $q->setParameter("fieldName", $wh); 
       } 

      $q->useResultCache(true) 
       ->setResultCacheLifetime(120) //Query Cache lifetime 
       ->setResultCacheId($queryCacheId) //Query Cache Id 
       ->getSingleResult(); 

    return $q 

} 
+0

這不是一個解決方案:'$ yourStuff'可以是一個數組,你如何處理這種情況? – DonCallisto 2015-02-23 08:50:31

+0

你可以把 - > where('x.yourStuff =?',$ yourStuff) in循環。 在你的邏輯函數中準備你的數組。 – 2015-02-23 09:04:49

+0

首先,這不是「容易」(你應該使用'和Where()'[在你的循環中]),其次你的回答並沒有強調,所以對我來說,這不是一個好的答案。請更新它 – DonCallisto 2015-02-23 09:08:01

0

下面是如何,你可以從一個單一的存儲庫緩存結果的功能的例子:

  • findOneBy(['foo' => 'bar'])
  • findOneByFoo('bar')
  • findOneBy(['bar' => 'foo', 'foo' => 'bar')
  • etc ...

它覆蓋了EntityRepository::FindOneBy函數。它遵循相同的簽名,因此不需要更新調用代碼。所有FindOneBy%類型的調用都會通過我們的實現findOneBy

<?php 
/** 
* MyObject Repo  
*/ 

namespace MyLib\Entity\Repository; 
use Doctrine\ORM\EntityRepository; 

class MyObjectRepository extends EntityRepository 
{ 

    const CACHE_KEY = 'my_object'; 
    const ALIAS = 'my_object'; 

    /** 
    * Override - use cache. 
    * 
    * @param array $criteria 
    * @param array|null $orderBy 
    * @return mixed 
    */ 
    public function findOneBy(array $criteria, array $orderBy = null) 
    { 
     $queryBuilder = $this->createQueryBuilder(self::ALIAS); 
     foreach($criteria as $field => $value) { 
      $queryBuilder->andWhere(self::ALIAS . ".{$field} = :{$field}")->setParameter($field, $value); 
     } 
     if (is_array($orderBy)) { 
      foreach ($orderBy as $field => $dir) { 
       $queryBuilder->addOrderBy($field, $dir); 
      } 
     } 
     $queryBuilder->setMaxResults(1); 

     $query = $queryBuilder->getQuery(); 

     $query->useResultCache(true, 3600, self::CACHE_KEY); 

     $result = $query->getResult(); 

     if ($result) return reset($result); 

     return $result; 
    } 

    /** 
    * Depending how you hydrate the entities may make more 
    * sense to use cache layer at findAll 
    * 
    * @param void 
    * @return array The entities. 
    */ 
    public function findAll() 
    { 
     $query = $this->getEntityManager()->createQuery('select v from \OAS\Entity\MyObject v'); 

     $query->useResultCache(true, 3600, self::CACHE_KEY); 

     $result = $query->getResult(); 

     return $result; 
    } 

    /** 
    * 
    */ 
    public function invalidateCache() 
    { 
     //this would depend on your cache implementation... 
     $container = \Zend_Registry::get('doctrine'); 

     $cache = $container->getCacheInstance(); 

     $cache->delete(self::CACHE_KEY); 
    } 
} 

這可能在過程中的一個更面向對象的方式進行,延長中介類,如果你想說的話有哪些簡單的開啓或關閉高速緩存存儲庫的屬性。您可以爲其他存儲庫操作功能擴展一個類似的方法。

+0

不正確的實現。所有查詢都將有一個緩存。 findOneBy(['name'=>'foo'],['name'=>'asc'])=== findOneBy(['title'=>'foo'],['title'=>'desc' ])=== findAll()' – ghost404 2017-04-10 11:13:45

+0

@ ghost404如果我明白你在說你錯了。 Doctrine二級緩存具有查詢意識。請參閱摘要中查詢對象的散列派生的$ querykey。至少很確定。我已經有了一些代碼,現在正在生產類似的代碼。 – ficuscr 2017-05-09 22:07:44

+1

你說得對。我犯了一個錯誤。 – ghost404 2017-05-10 09:08:20