对查询进行分页
问题中没有显示代码,但我们假设您从一个简单的烘焙控制器索引操作开始:
public function index()
{
$this->set('posts', $this->paginate($this->Posts));
$this->set('_serialize', ['posts']);
}
首先,认识到控制器方法 paginate accepts a table or query object - 如果传递了一个表对象,则分页器组件 simply calls find 与查询对象一起工作。所以,上面的代码在功能上等价于:
public function index()
{
$query = $this->Posts->find();
$this->set('posts', $this->paginate($query));
$this->set('_serialize', ['posts']);
}
使用查询缓存方式
只需对上述代码稍作修改即可使用查询的缓存方法:
public function index()
{
$query = $this->Posts->find();
$cacheKey = $this->name . '_' . md5(json_encode($this->request->query));
$query->cache($cacheKey);
$this->set('posts', $this->paginate($query));
$this->set('_serialize', ['posts']);
}
查询参数和控制器名称用于生成唯一的缓存键,以便一次调用分页的缓存结果不会与不同请求的缓存结果混淆。
照顾计数
以这种方式使用时仍然会发出计数,如果这是一个问题,仍然可以通过定义a counter callback来防止它:
public function index()
{
$query = $this->Posts->find();
$cacheKey = $this->name . '_' . md5(json_encode($this->request->query));
$searchTerms = []; // define this
$countCacheKey = $this->name . '_' . md5(json_encode($searchTerms)) . '_count';
$query
->cache($cacheKey)
->counter(function($query) use ($countCacheKey) {
return Cache::remember($countCacheKey, function() use ($query) {
return $query->count();
});
});
$this->set('posts', $this->paginate($query));
$this->set('_serialize', ['posts']);
}
即只需将 count 方法的调用封装在 Cache::remember 中即可。
请注意,答案中用于计数的缓存键对于所有请求都是相同的,因为在此示例中要分页的行数对于所有请求都相同。例如,如果您对搜索进行分页 - 搜索词应用于计数缓存键。