2015-02-23 15 views
6

Sto lavorando al progetto symfony 2.5 con doctrine 2.4.Come memorizzare nella cache la query "findOneBy()" con l'id della cache e l'opzione cache lifetime in Symfony 2.4?

Desidero memorizzare nella cache il risultato della query con l'id della cache e il tempo di cache, in modo da poter eliminare il risultato della cache, ogni volta che è necessario tramite admin.

Sono in grado di memorizzare nella cache il risultato della query con l'opzione "createQueryBuilder()".

Esempio:

$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(); 

Ma io non sono in grado di trovare il modo simile a Chache risultato della query per l'opzione "findOneBy()".

Esempio:

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

Sto cercando una soluzione adeguata, ogni aiuto è molto apprezzato.

+1

https://groups.google.com/d/msg/doctrine-user/RIeH8ZkKyEY/HnR7h2p0lCQJ Come dice Ocramius, si Nedd eseguire l'override di questo metodo in pronti contro termine, se si vuole approfittare delle operazioni di caching. – DonCallisto

+0

Grazie per la risposta. Fammi provare e ti chiederemo di più se necessario. –

+0

Questo è il modo in sovrascrivo funzione "findOneBy" in classe repository funzione pubblica findOneBy (array $ criteria_array) { \t \t $ query = $ this-> createQueryBuilder ('b') -> selezionare ('b'); \t \t foreach ($ criteria_array come $ criteri fieldName => $) { \t \t \t $ query-> andwhere ("b $ fieldName =:. $ FieldName"); \t \t \t $ query-> setParameter ("$ fieldName", $ criteri); \t \t} \t \t ritorno $ query-> getQuery() \t \t \t -> useResultCache (vero) \t \t \t -> setResultCacheLifetime (120) \t \t \t -> setResultCacheId ($ queryCacheId) \t \t \t -> getResult(); } Si prega di rivedere e correggere me. Devo sovrascrivere la funzione "trova *" in tutti i repository ogni volta che ho bisogno di memorizzare i risultati nella cache? –

risposta

0

Effettuare una funzione comune per questo.

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

seguito dal vostro funzione comune:

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

Questa non è una soluzione: '$ yourStuff' potrebbe essere un array, come gestisci questo caso? – DonCallisto

+0

puoi inserire -> dove ('x.yourStuff =?', $ YourStuff) in loop. prepara la tua matrice nella tua funzione logica. –

+0

Per prima cosa, non è "facile" (dovresti usare 'andWhere()' [nel tuo ciclo]), in secondo luogo la tua risposta non ha evidenziato che così, per me, non è una buona risposta. Si prega di aggiornare il codice – DonCallisto

0

Ecco un esempio di come si può memorizzare nella cache i risultati da un unico repository per le funzioni:

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

Sostituisce la funzione EntityRepository::FindOneBy. Segue la stessa firma quindi non è necessario aggiornare il codice di richiamo. Tutte le chiamate di tipo FindOneBy% passeranno attraverso la nostra implementazione di 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); 
    } 
} 

questo potrebbe essere fatto in più di moda OOP, naturalmente, che si estende una classe intermedia, se si voleva dire che ha una proprietà sul repository, che semplicemente attivata la cache on o off. È possibile estendere un approccio simile per le altre funzioni operative del repository.

+0

Implementazione errata. Avrai una cache per tutte le query. 'findOneBy (['name' => 'foo'], ['name' => 'asc']) === findOneBy (['title' => 'foo'], ['title' => 'desc' ]) === findAll() ' – ghost404

+0

@ ghost404 Se capisco cosa stai dicendo, hai torto. La cache di secondo livello di Doctrine è consapevole della query. Vedi '$ querykey' derivato dall'hash dell'oggetto query nell'abstract. Piuttosto sicuro, almeno. Ho il codice che fa simili da anni in produzione ora. – ficuscr

+1

Hai ragione. Ho fatto un errore. – ghost404

Problemi correlati