2017-02-21 32 views
0

我有消息实体存储库,并且我想缓存结果以获取这些消息的查询。但是提取存储库函数将结果划分为页面,因此存在偏移和限制。使用原则symfony清除只有一个实体/存储库的结果缓存

唯一的想法是如何让这个存储库的结果缓存失效,就是生成并记住另一个缓存项中的每个缓存ID,然后使用该条目使其全部无效。

是否有更好的解决方案来解决这个问题,所以我可以简单地只对一个实体/存储库使结果缓存失效?

编辑︰我刚刚发现缓存ID不用于唯一查询,但它缓存所有查询,即使它们的变量更改。

public function getMessages($offset, $limit, $search = null){ 
    $builder = $this->createQueryBuilder('m') 
     ->orderBy('m.id', 'DESC') 
     ->setFirstResult($offset) 
     ->setMaxResults($limit); 

    if($search !== null){ 
     $builder->where('m.title LIKE :searchQuery OR m.content LIKE :searchQuery') 
      ->setParameter('searchQuery', '%'.$search.'%'); 

     return $builder->getQuery()->getResult(Query::HYDRATE_ARRAY); 
    } else { 
     return $builder->getQuery() 
      ->useResultCache(true, null, 'message_messages') 
      ->getResult(Query::HYDRATE_ARRAY); 
    } 
} 

所以我有4条消息,并且我已经设置为每页显示2条消息。所以第一个查询有0偏移量和2个限制,第二个查询有2个偏移量和2个限制。

然后会发生什么,两个查询缓存在单个缓存ID下。我已经从phpMyAdmin进行了更改,并且这两个页面都保持不变,这意味着两者都使用了缓存。当我使'message_messages'缓存ID无效时,两个页面都发生了变化,并且phpMyAdmin所做的更改现在可见。

我只想说,这是工作,我希望它如何工作。但我不确定它是否不是某种未定义的行为?

+0

您是否找到解决方案或者您还在寻找解决方案? –

+0

为了给你的缓存提供唯一性,你应该在偏移量之后构造缓存的名字,所以如果你当前的偏移量是'0',那么你的缓存名变成'message_messages_0'等等。尝试' - > useResultCache(true,null,'message_messages _'。$ offset)'。我希望我理解正确!?另外看看这个:http://www.inanzzz.com/index.php/post/ck9l/using-doctrine-apc-caching-with-query-builder-in-symfony – BentCoder

+0

@ Charles-AntoineFournel我发现我找到了一个解决方案,但BentCoder说我应该为每个解决方案构建唯一的ID,并且从我对帖子进行编辑时所检查和描述的内容中,ID将对所有查询进行分组。当我使用单个ID进行许多偏移时,它们仍然全部被缓存,并且我可以通过清除这个ID来使所有页面无效。 –

回答

0

我所以这可能是其他人显而易见的,但我认为,如果我useResultCache与ID为例如。 “resultCacheId1”,然后我将再次使用相同的缓存,第二次使用会覆盖第一个缓存。但我发现的是,它是根据一个缓存ID分组,像这样:

的相同的功能,从我的问题,我会刚刚摆脱$搜索$限制参数简化它的:

public function getMessages($offset){ 
    $builder = $this->createQueryBuilder('m') 
     ->orderBy('m.id', 'DESC') 
     ->setFirstResult($offset) 
     ->setMaxResults($limit) 
     ->getQuery() 
     ->useResultCache(true, null, 'message_messages') 
     ->getResult(Query::HYDRATE_ARRAY); 

} 

出于测试目的,获取和了解一下什么是缓存里面我用:

$em->getConfiguration()->getResultCacheImpl()->fetch('message_messages') 

如果我使用功能,一旦像getMessages(0)它会出现在缓存中:

array:1 { 
    "SELECT ... FROM message m0_ ORDER BY m0_.id DESC LIMIT 2 OFFSET 0-a:0:{}-a:0:{}" => array:2 { 
     0 => array:4 {id: 6, title: '...', content: '...', date: '...'}, 
     1 => array:4 {id: 5, title: '...', content: '...', date: '...'}, 
    } 

}

当我再次使用它像这样getMessages(1),将另一项添加 'message_messages' 缓存ID:

array:1 { 
    "SELECT ... FROM message m0_ ORDER BY m0_.id DESC LIMIT 2 OFFSET 0-a:0:{}-a:0:{}" => array:2 { 
     0 => array:4 {id: 6, title: '...', content: '...', date: '...'}, 
     1 => array:4 {id: 5, title: '...', content: '...', date: '...'}, 
    }, 
    "SELECT ... FROM message m0_ ORDER BY m0_.id DESC LIMIT 2 OFFSET 2-a:0:{}-a:0:{}" => array:2 { 
     0 => array:4 {id: 4, title: '...', content: '...', date: '...'}, 
     1 => array:4 {id: 3, title: '...', content: '...', date: '...'}, 
    } 

}

并使其无效,我可以使'message_messages'缓存ID无效。 因此,我不需要为每个偏移量生成缓存ID,例如message_messages_0,message_messages_1,message_messages_2等等,然后在循环中使它们全部失效。