【问题标题】:CakePHP 3: find() with cacheCakePHP 3:带有缓存的 find()
【发布时间】:2015-04-17 10:23:05
【问题描述】:

关于get()方法,我看了here

Like find() get 集成了缓存。调用 get() 时可以使用 cache 选项进行通读缓存

但后来在find()方法(here)的专用部分中,没有提到缓存,没有缓存示例,支持的选项中也没有提到cache选项。

所以我想知道:我可以将cache 选项与find() 方法一起使用吗?如果有,怎么做?

谢谢。


感谢 ndm。所以:

$query = $this->Pages->find('all');
$query->cache('all_pages');

$this->set('pages', $query->all());

或者(更简单):

$query = $this->Pages->find('all')->cache('all_pages');

$this->set('pages', $query->all());

【问题讨论】:

    标签: cakephp caching cakephp-3.0


    【解决方案1】:

    查询生成器不支持通过选项进行缓存,它有一个单独的方法可以使用,Query::cache(),您可以像这样使用它

    $query = $table->find();
    $query->cache('cache_key');
    
    $query->cache('cache_key', 'configName');
    
    $query->cache(function($query) {
        return md5(
            serialize($query->clause('select')) .
            serialize($query->clause('where'))
        );
    });
    
    // ...
    

    get() 支持通过选项进行缓存,因为这是配置内部 find 调用的唯一方法,因为它会立即执行,以便get() 可以返回抛出可能的错误并返回一个实体。

    【讨论】:

    • 谢谢@ndm。我可以举一个完整的例子吗?我不知道如何同时使用cache()find() 方法。
    • @MirkoPagliai 一个完整的例子?究竟是什么?除了此处显示并在文档中解释的内容之外,您还需要了解什么?
    • 类似this 的例子(使用CakePHP 2.x)。
    • @MirkoPagliai 好吧,CakePHP 3.x 没有什么花哨的东西,你需要做的就是在你的查询中调用 cache() 方法(如果你不这样做,可能会创建一个缓存配置)不想使用默认的),剩下的就是魔法:)
    • @shylajhaa 查询将在设置了相应的缓存键时自动读取它们。只要您使用相同的缓存配置(Query::cache()Cache::read() 的第二个参数),手动读取它也将起作用。
    【解决方案2】:

    我已经调查了 cakephp 3 文档和其他资源,以获得使用 cache() 进行查询的良好示例,但没有找到任何(文档仅提供简短的示例,而不是完整示例)

    我的模型 /src/Model/Table/MetaTagTable.php 中的方法存在非常相似的问题

    namespace App\Model\Table;
    
    use Cake\ORM\Table;
    
    class MetaTagTable extends Table
    {
        /**
         * Get meta tags from db table
         * 
         * @return array
         */
        function getMetaTags($controller, $action, $hasSearchParamFlag)
        {
            $hasSearchParamFlag = (int) $hasSearchParamFlag;
    
            return $this
                ->find()
                ->select(['tag', 'type'])
                ->where(
                    [
                        'controller'=> $controller,
                        'action'=> $action,
                        'have_search_param'=> $hasSearchParamFlag,
                    ]
                )
                ->all()
                ->cache(
                    function () use ($controller, $action, $hasSearchParamFlag) 
                    {
                        return "getMetaTags-$controller, $action, $hasSearchParamFlag";
                    },
                    'middle'
                );
        }
    }
    

    上面的例子显示了一个致命错误:

    Error: Call to undefined method Cake\ORM\ResultSet::cache()  
    

    official cakephp 3 doc 没有提供完整的示例,说明 cache() 与查询构建器的工作原理,因此使用@ndm 答案并尝试几种不同的代码变体,我使我的代码工作,只是移动 cache() 调用在 ->all() 方法调用之前:

    function getMetaTags($controller, $action, $hasSearchParamFlag)
    {
        $hasSearchParamFlag = (int) $hasSearchParamFlag;
    
        return $this
            ->find()
            ->select(['tag', 'type'])
            ->where(
                [
                    'controller'=> $controller,
                    'action'=> $action,
                    'have_search_param'=> $hasSearchParamFlag,
                ]
            )                              
            ->cache(
                function () use ($controller, $action, $hasSearchParamFlag) 
                {
                    return "getMetaTags-$controller, $action, $hasSearchParamFlag";
                },
                'middle'
            )                        
            ->all()
            ->toArray();
    }
    

    因为 cache() 方法属于 trait "QueryTrait",并且需要为 Cake\ORM\Query 类调用 cache() 方法,而不是为 Cake\ORM\ResultSet。

    现在一切正常,尽情享受吧!

    【讨论】:

    • 很简单,all() 方法返回一个ResultSetInterface 实例,所以你必须最后调用它。 p.s.连续调用all()toArray() 是多余的
    猜你喜欢
    • 1970-01-01
    • 2018-03-15
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-22
    • 1970-01-01
    相关资源
    最近更新 更多