How to cache doctrine "findOneBy ()" with cache parameter and cache usage time in Symfony 2.4?

I am working on a symfony 2.5 project with doctrine 2.4.

I want to cache the result of the request with the cache identifier and cache time, so I can delete the cache result when necessary, although the administrator.

I can cache the result of the query using the option "createQueryBuilder ()".

Example:

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

But I cannot find a similar way for the result of the chache request for the "findOneBy ()" option.

Example:

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

I am looking for a suitable solution, any help is greatly appreciated.

+6
source share
3 answers

You need to override each findBy * or findOneBy * function in the user repository: this is the only way, since the default behavior of doctrine2 does not take this situation into account. Sorry, up to you.

Also Ocramius (Doctrine2 devel) says it here https://groups.google.com/d/msg/doctrine-user/RIeH8ZkKyEY/HnR7h2p0lCQJ

+2
source

Make a general function for this.

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

Next is your general function:

  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
source

Here is an example of how you can cache results from a single repository for functions:

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

It overrides the function EntityRepository::FindOneBy . It follows the same signature, so there is no need to update the calling code. All calls of type FindOneBy% will go through our findOneBy implementation.

 <?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); } } 

This can be done, for example, in a more OOP style, expanding the intermediate class if you want to say that it has a property in the repository that just turned on or off the cache. You can extend a similar approach for other operations with repository operations.

0
source

Source: https://habr.com/ru/post/982876/


All Articles