如何缓存学说" findOneBy()"在Symfony 2.4中查询缓存ID和缓存生命周期选项?

时间:2015-02-23 06:33:53

标签: php symfony caching doctrine-orm

我正在使用doctrine 2.4开发symfony 2.5项目。

我想使用缓存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();

但我无法找到与“findOneBy()”选项的chache查询结果类似的方法。

示例:

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

我正在寻找一些合适的解决方案,非常感谢任何帮助。

3 个答案:

答案 0 :(得分:4)

您需要将每个findBy *或findOneBy *函数重新定义到自定义存储库中:这是doctrine2默认行为不考虑这种情况的唯一方法。 不幸的是,由你决定。

Ocramius(Doctrine2 devel)也在这里说https://groups.google.com/d/msg/doctrine-user/RIeH8ZkKyEY/HnR7h2p0lCQJ

答案 1 :(得分: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

 }

答案 2 :(得分:0)

以下是如何从单个存储库缓存函数结果的示例:

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

它会覆盖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);
    }
}

当然,这可以以更多的OOP方式完成,扩展一个中间类,如果你想说在存储库上有一个属性,它只是打开或关闭缓存。您可以为其他存储库操作函数扩展类似的方法。