让Doctrine默认使用结果缓存

4
我正在将Memcache绑定到Doctrine,看起来我必须在每个查询中显式地使用useResultCache。是否可以将其默认设置为true,并具有在不需要时使用useResultCache(false)的能力?

你已经找到解决办法了吗? - Ascherer
3个回答

9
创建一个包装类/函数,明确设置useResultCache(true),并在所有地方使用它,而不是使用原生函数。

我试图避免修改每个查询。这个解决方案仍然需要修改吗? - Fluffy

6
我知道这个问题很旧,但我将写出我想到的最好答案。
1)将依赖项抽象化为接口(即使用依赖注入模式将EntityManager注入到创建查询的类中,并使用EntityManagerInterface)。
现在,要么:
a)[更好,但更长] 为EntityManagerInterface创建一个新的与组合相关的实现,它将代理对原始entityManager的调用,并将结果缓存标志设置为true:
<?php
class CachedEntityManager implements EntityManagerInterface { 

private $proxiedManager;

public function __construct(EntityManagerInterface $proxiedManager) {   
    $this->proxiedManager = $proxiedManager;    
}

public function createQuery($dql = '') {
    $query = $this->proxiedManager->createQuery($dql);
    $query->useResultCache(true);   
}

[... proxy all the calls forth to proxiedManager ...]

}
b) [不太好,但更短] 扩展EntityManager类并覆盖createQuery方法。请记住,这通常不是一个好习惯,您绝对不应该再在该类中编写任何内容,而应重构为a):
<?php
class CachedEntityManager extends EntityManager { 

public function createQuery($dql = '') {
    $query = parent::createQuery($dql);
    $query->useResultCache(true);   
}

}

@Jarrett 引用 EntityManager DocBlock 的话:您永远不应该尝试继承 EntityManager:继承不是 EntityManager 的有效扩展点。相反,您应该查看 {@see \Doctrine\ORM\Decorator\EntityManagerDecorator} 并在装饰器中包装您的实体管理器。 然而,这仍然没有回答 为什么 - Taylan

2
您可以通过在\Doctrine\ORM\AbstractQuery中将$_useResultCache的默认值设置为TRUE来稍微修改Doctrine核心。这将使所有查询默认使用resultCacheDriver,并且您可以轻松地关闭单个查询的缓存,使用$query->useResultCache(FALSE)即可。
这是一个有用的小技巧,可以节省很多打字时间,但要小心;我发现缓存驱动程序不会缓存尚未初始化的延迟加载关联(现在想想很明显)。有时候为每个单独的查询打开结果缓存更安全。

2
我意识到建议黑掉核心可能会让我遭受贬值,但是楼主的评论表明他们不想重新编写每个查询。如果是这种情况,那么黑客AbstractQuery是最简单的解决方案。 - WildlyInaccurate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接