代码之家  ›  专栏  ›  技术社区  ›  Andy

cakephp3.xorm如何知道从哪个缓存文件读取而不显式地定义它?

  •  1
  • Andy  · 技术社区  · 7 年前

    CakePHP 3.5.13版

    在控制器方法中,我缓存数据库查询,如下所示:

    $substances = TableRegistry::get('Substances');
    $query = $substances->find()->limit($limit)->offset($offset);
    $query->cache(function ($query) {
        return 'substance_results_' . md5(serialize($query->sql()));
    });
    $this->set('data', $query->all());
    

    127.0.0.1:6379> keys *
    3) "cake_redis_substance_results_cb799f6526c148d133ad9ce9245b23be"
    4) "cake_redis_substance_results_dbc7b0b99dff3ab6a20cbdfbbd09be8c"
    

    如果相同的查询( $query )再次执行时,Cake将读取相应缓存文件的内容。 我们告诉它钥匙的名字 但不是 .

    $query->cache(function ($query) {
        return 'foo_' . md5(serialize(time()));
    });
    

    在这里,我制作了一个完全不同的键,它不是基于正在执行的SQL。代码的任何部分都不会告诉它哪个键对应于哪个查询。

    文件( https://book.cakephp.org/3.0/en/orm/query-builder.html#caching-loaded-results )缓存加载的结果并不能解释ORM的这一点。上面写着:

    添加 将结果缓存到自定义查找程序或通过事件侦听器。

    当缓存查询的结果 取来 ...

    我已经阅读了文档的一些部分,这些部分告诉您如何以一种通用的、非ORM特定的方式(使用 Cache::read($key) )但这和ORM自动完成是完全不同的。如果是 你必须提供一把钥匙( $key

    有人能澄清一下吗?

    1 回复  |  直到 7 年前
        1
  •  2
  •   ndm    7 年前

    食谱很可能没有提到额外的要求,因为没有任何要求。

    写作 当然,必须与的缓存键相同 阅读 ,其他任何东西都没有任何意义(查询将使用您传递给 QueryTrait::cache() 阅读和写作的方法,也就是说 显式定义用于读取的键,就在您传递的闭包中。

    检查 the method description

    /**
     * Enable result caching for this query.
     *
     * If a query has caching enabled, it will do the following when executed:
     *
     * - Check the cache for $key. If there are results no SQL will be executed.
     *   Instead the cached results will be returned.
     * - When the cached data is stale/missing the result set will be cached as the query
     *   is executed.
     *
     * ### Usage
     *
     * ```
     * // Simple string key + config
     * $query->cache('my_key', 'db_results');
     *
     * // Function to generate key.
     * $query->cache(function ($q) {
     *   $key = serialize($q->clause('select'));
     *   $key .= serialize($q->clause('where'));
     *   return md5($key);
     * });
     *
     * [...]
     *
     * @param false|string|\Closure $key Either the cache key or a function to generate the 
     *   cache key. When using a function, this query instance will be supplied as an argument.
     *
     * [...]
     */
    

    每次执行查询时,它都会检查您是否传递了缓存键,并计算并使用它相应地读写缓存结果。因此,您必须确保缓存键是“静态”的,这样整个查询缓存就可以使用了。

    可以使用闭包动态地构建键,但结果必须是静态的,即对于同一查询,每次调用它时都必须生成相同的键。有一个原因

    我之前提到过,这种情况发生在 \Cake\Datasource\QueryTrait::all() \Cake\Datasource\QueryCacher::fetch()