Zf2 - Doctrine2 - 缓存关系查找查询

时间:2013-09-23 22:02:46

标签: caching doctrine-orm zend-framework2

我正在构建一个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查询。如何以递归方式缓存整个查询?

1 个答案:

答案 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',
        ),
    ),
),