2013-09-23 87 views
0

我正在构建一个ZF2 + Doctrine2 Web应用程序,并在我的Entity Repositories中实现了缓存。Zf2 - Doctrine2 - 缓存关系查询查询

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查询。我如何缓存整个查询/递归?

回答

2

简而言之,你不能。学说为延迟加载执行“魔术”查询。例如,如果加载用户,则角色不是自动查询。只有在您致电$user->getRole()时才会查询角色。

此行为需要所谓的代理模式。代码中的用户不是Admin\Entity\User对象,而是从您的用户扩展而来的Doctrine类。该代理还包含实体管理器的实例,因此当您致电getRole()时,它可以查询角色。因为如果这个代理,很难序列化和反序列化php对象。

由于这种模式,你永远无法真正缓存Doctrine实体。代理和关系也会一直存在问题。您可以加载它们的唯一方法是不加载相关实体并确保loading technique for __wakeup()

如果您只是使用Doctrine caches,这会更容易。你可以用这段代码在你的配置配置主义缓存与ZF2 DoctrineModule:

'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', 
     ), 
    ), 
), 
+0

我在配置中有一段代码。但是,使用ZendDeveloperTools,我注意到它实际上并没有缓存我的查询结果。一旦我实现了自定义实体存储库并手动调用useResultCache(),查询就开始从缓存中提取结果。我完全理解你对代理模式行为的解释。 – jas

+0

如果查询缓存不起作用,它必须是一个错误。有两种选择:1)ZDT在缓存时也显示查询(所以这会让你感到困惑),或者2)缓存不起作用。如果后者是这种情况,你能否在Github上报告一个问题? –