2017-02-21 28 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等等,然後在循環中使它們全部失效。