我使用Laravel分页(https://laravel.com/docs/6.x/pagination#paginating-eloquent-results),如下所示:
// the Controller contains
$users = App\User::paginate(15);运行这段代码时,我注意到执行了两个查询:
获取总项目数的select count(*) as aggregate from user
select * from user limit 15 offset 0我想缓存这个查询,问题是:从App\User::paginate(15)中是否有一种方法可以获得将执行的sql?select count(*) as aggregate from user和select * from user limit 15 offset 0
代码App\User::paginate(15)返回一个LengthAwarePaginator类;我可以从这个类执行sql吗?
这个想法是创建我自己的方法来缓存这个分页请求。类似于:
// the Model contains
public static function paginateWithQueryCache($itemPerPage) {
$query = self::query();
$cacheKeyString = $query->toSql();
$cacheKeyStringMD5 = md5($cacheKeyString);
return \Cache::remember($cacheKeyStringMD5, 60, function() use ($itemPerPage) {
return self::paginate($itemPerPage);
});
}// the Controller will be update with
$users = App\User:: paginateWithQueryCache(15);这里的问题是,用作缓存键的$query->toSql()是对模型(select * from user)的简单查询,而不是分页查询(select * from user limit 15 offset 0);这是切换到第二页page=2的问题。
谢谢。
发布于 2019-11-13 09:20:08
查询select count(*) as aggregate from user (在我的例子中,数据库表中有数百万条记录)是从Illuminate\Database\Query::getCountForPagination()执行的,然后为了缓存它,我需要扩展类并实现缓存。
我更改了方法,并决定缓存所有分页输出:
// Controller
public function paginateCache($model, $cacheExpireInSeconds = 120)
{
$cacheKeyString = request()->fullUrl();
$cacheKeyStringMD5 = md5($cacheKeyString);
/* Closure to get data */
$func_get_data = function() use ($model) {
return $model::paginate(1000);
};
/* Caching */
return \Cache::remember($cacheKeyStringMD5, $cacheExpireInSeconds, $func_get_data);
}
public function index()
{
return $this->paginateCache(User::class);
}https://stackoverflow.com/questions/58821151
复制相似问题