在 isEmpty 条件下,cakephp 缓存不起作用

In isEmpty condition cakephp cacheing not working

我正在尝试缓存查询,条件是在第一次请求之后并且如果查询对象不为空我想缓存。我试过如下

 public function getCategories()
 {   
        $categoriesTable = TableRegistry::getTableLocator()->get( 'Categories' );
    
        if(\Cake\Cache\Cache::read('categories', 'redis_cache') == null)
        {
            $categories = $categoriesTable->find();
    
            if(!$categories->isEmpty())
            {
                print("hello");
                $categories->cache('categories','redis_cache');
                debug(\Cake\Cache\Cache::read('categories', 'redis_cache'));
            }
            $this->set('categories',$categories);
        }else{
            $this->set('categories',\Cake\Cache\Cache::read('categories', 'redis_cache'));
        }
    
        $this->viewBuilder()->setOption('serialize', ['categories']); 
}

我在 postman 中得到的输出

第一次命中

hello
null 

第二次命中

hello
null 

但评论后if(!$categories->isEmpty())条件

第一次命中

{
    "categories": [
        {
            "id": 2,
...
}

此外,如果我像下面这样写条件,它也可以正常工作。

if(!$categoriesTable->find('all')->isEmpty()). // it's working 

我在这里做错了什么?

Queries are lazy evaluated,这意味着它们在实际请求数据之前不会被执行,但是 isEmpty() 是导致查询被执行的方法之一,它需要结果告诉有没有。

您的代码在 afterwards 后设置了查询缓存器配置,这将没有任何效果,因为进一步的 evaluation/iteration 查询对象将不会再次执行查询(这是当它通常缓存其结果时),而是访问 运行时间缓冲的结果,因此没有数据被缓存。

如果您需要更多地控制缓存的处理方式,那么您可能希望避免 built-in 查询缓存,完全手动执行,例如读取和 写入 根据需要缓存。

就您的用例而言,如果您有一个删除和重新生成数据的脚本 运行ning,您可能需要考虑在之后 clear the cache 使用它(bin/cake cache clear redis_cache).然后,如果你在前端实现“再试一次直到有数据”逻辑,你的后端代码可以简化为只读取和缓存任何数据,如果有none 但是,您的前端会让用户知道数据尚未准备好并再次轮询。虽然 websockets 或服务器发送的事件可能更好,但长轮询肯定比脚本 运行 分钟结束更可取。