我正在使用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));
我正在寻找一些合适的解决方案,非常感谢任何帮助。
答案 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方式完成,扩展一个中间类,如果你想说在存储库上有一个属性,它只是打开或关闭缓存。您可以为其他存储库操作函数扩展类似的方法。