与您和 Active Records 一起使用 memcached

Working with memcache with Yii and ActiveRecords

所以我一直在尝试让 memcache 在我的网站上工作 运行 Yii 2。我已经为 DB schema 的东西工作了缓存,但它似乎不适用于 ActiveRecord 查询.

这是我的数据库配置:

'db' => [
    'class'                 => 'yii\db\Connection',
    'dsn'                   => 'mysql:host=127.0.0.1;dbname=db_name',
    'username'              => 'user_name',
    'password'              => 'password',
    'charset'               => 'utf8',
    'enableQueryCache'      => true,
    'queryCache'            => 'cache',
    'queryCacheDuration'    => 600,
    'enableSchemaCache'     => true,
    'schemaCache'           => 'cache',
    'schemaCacheDuration'   => 3600,
]

根据指南 (http://www.yiiframework.com/doc-2.0/guide-caching-data.htm),这应该足以让全局缓存正常工作。根据我的理解,如果设置了这些变量,那么它应该在指定的时间内缓存所有查询,或者我是否仍然需要专门调用以下内容?

$result = Customer::getDb()->cache(function ($db) {
    return Customer::find()->where(['id' => 1])->one();
});

我深入研究了代码库以查看发生了什么,\yii\db\Connection::getQueryCacheInfo() 中的内容看起来已更改为如下所示:它将完美运行:

public function getQueryCacheInfo($duration, $dependency)
{

    if (!$this->enableQueryCache) {
        return null;
    }

    $duration = (isset($duration)) ? $duration : $this->queryCacheDuration;
    $dependency = (isset($dependency)) ? $dependency : $this->queryCache;

我是不是做错了什么?为什么我不能让内存缓存默认用于所有查询?

谢谢

如果你真的想要缓存 "for all queries" 你最好启用数据库的查询缓存。它在这方面要好得多。除了数据库架构之外,除非您明确启用它,否则不会进行缓存,就像您的示例中那样。

documentation for $enableQueryCache 明确指出:

Whether to enable query caching. Note that in order to enable query caching, a valid cache component as specified by $queryCache must be enabled and $enableQueryCache must be set true. Also, only the results of the queries enclosed within cache() will be cached.

如果你真的想这样做,有一种方法可以破解它,但我认为这不值得:
创建您自己的 ActiveQuery 衍生 class。在其 createCommand() 方法中已经在 returning 命令对象之前启用缓存:

class MyActiveQuery extends ActiveQuery 
{
   public function createCommand($db = null)
   {
      $command = parent::createCommand(db);
      $command->cache();
      return $command;
   }
}

然后你必须覆盖每个 ActiveRecord class 的 find() 方法,你希望缓存到 return 你的 ActiveQuery 实例代替。

public static function find()
{
    return Yii::createObject(MyActiveQuery::className(), [get_called_class()]);
}