Yii2:如何缓存活动数据提供者?

off*_*ine 11 php caching dataprovider yii2

在我的PostSearch模型中,我有这个代码:

public function search($params)
{
    $query = Post::find()->where(['status' => 1]);

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
        'sort'=> ['defaultOrder' => ['id' => SORT_DESC]],
        'pagination' => [
            'pageSize' => 10,
        ]
    ]);

    if (!($this->load($params) && $this->validate())) {
        return $dataProvider;
    }

    $query->andFilterWhere([
        'id' => $this->id,
        'status' => $this->status,
    ]);

    $query->andFilterWhere(['like', 'title', $this->title])
        ->andFilterWhere(['like', 'text', $this->text]);

    return $dataProvider;
Run Code Online (Sandbox Code Playgroud)

我的尝试,而不是上面的行return $dataProvider,将是这段代码:

$dependency = [
    'class' => 'yii\caching\DbDependency',
    'sql' => 'SELECT MAX(updated_at) FROM post',
];

$result = self::getDb()->cache(function ($db) {
    return $dataProvider;
}, 3600, $dependency);

return $result
Run Code Online (Sandbox Code Playgroud)

我想根据updated_at字段缓存ADP返回的结果.我的意思是我想从缓存中提供数据,直到做出一些改变.我的代码不起作用,我的意思是缓存根本不适用.我做错了什么,是否有可能在ADP上做到这一点?谢谢

Bli*_*izz 16

在实例化之后几乎没有使用缓存数据提供程序,因为在准备之前它实际上并没有对数据库进行任何选择.所以你实际上就像现在一样缓存一个空对象实例.

如果您有一组非常大的记录,请prepare()在缓存中提前调用dataProviders :

 self::getDb()->cache(function ($db) use ($dataProvider) {
     $dataProvider->prepare();
 }, 3600, $dependency);
 return $dataProvider;
Run Code Online (Sandbox Code Playgroud)

这实际上会缓存dataProvider运行的任何查询,因此下次将从查询缓存中获取它们.这应该会产生你想要的东西.

如果你有一个有限数量的记录,一次缓存它们也可以工作:

$key = 'MyCachedData'; // + Data uniquely referring to your search parameters
$cache = \Yii::$app->cache;
$dataProvider = $cache->get($key);
if (!$dataProvider) {
   $dependency = \Yii::createObject([
      'class' => 'yii\caching\DbDependency',
      'sql' => 'SELECT MAX(updated_at) FROM post',
   ]);

   $dataProvider = new \yii\data\ArrayDataProvider;
   $dataProvider->allModels = $query->all();
   $cache->set($key, $dataProvider, 3600, $dependency) 
} 
return $dataProvider;
Run Code Online (Sandbox Code Playgroud)

显然,这对于较大的数据集来说并不理想,但这取决于您要查找的内容.