我正在构建一个ZF2 + Doctrine2 Web应用程序,并且已在我的实体存储库中实现了缓存。
public function findActive()
{
$query = $this->_em->createQueryBuilder();
$query->select('r')
->from('Admin\Entity\Brands', 'r')
->where('r.deleted = false')
->orderBy('r.name', 'ASC');
return $query->getQuery()
->useResultCache(true, 7200, 'brands_find_active')
->getResult();;
}
我无法弄清楚如何为查询查询注入缓存逻辑。
就像我有一个带有role_id的用户表,该用户表链接到角色表并执行getRole()->getRoleName()
调用。这会导致对角色表进行额外的SQL查询。如何以递归方式缓存整个查询?
答案 0 :(得分:2)
简单地说,你不能。 Doctrine为延迟加载执行“魔术”查询。例如,如果您加载用户,则角色不会自动查询。只有当您致电$user->getRole()
时,才会查询该角色。
此行为需要所谓的代理模式。代码中的用户不是Admin\Entity\User
对象,而是来自用户的Doctrine类。代理还拥有实体管理器的实例,因此当您调用getRole()
时,它可以查询角色。因为如果使用这个代理,很难对php对象进行序列化和反序列化。
由于这种模式,你永远无法真正缓存Doctrine实体。你也经常遇到代理和关系问题。加载相关实体的唯一方法是不加载loading technique for __wakeup()
。
如果你只使用Doctrine caches,那就容易多了。您可以在配置中使用ZF2 DoctrineModule配置Doctrine缓存:
'doctrine' => array(
'configuration' => array(
'orm_default' => array(
'metadata_cache' => 'apc',
'query_cache' => 'apc',
'result_cache' => 'apc',
),
),
),
如果您需要为apc缓存提供命名空间(例如,您在一台服务器上有多个站点),请通过此配置设置命名空间:
'doctrine' => array(
'cache' => array(
'apc' => array(
'namespace' => 'my-namespace',
),
),
),