Laravel: Кэширование Eloquent — Что нужно знать
Для этого используется класс Cache
.
В примерах мы попытаемся оптимизировать вызов базы данных, который берёт из неё 10000 записей.
Основы кэширования
Для кэширования набора данных используйте функцию Cache::remember()
:
app/Http/Controllers/ProductsController.php:
use Illuminate\Support\Facades\Cache;
// ...
Cache::remember('KEY', TIME_IN_SECONDS, function () {
return Model::get(); // или другой eloquent запрос
});
Кэширование результатов Eloquent модели
Например, мы получим все записи из Eloquent модели Product
и кэшируем их на 60 минут.
app/Http/Controllers/ProductsController.php:
use Illuminate\Support\Facades\Cache;
// ...
public function index()
{
$products = Cache::remember('products_list', 60 * 60, function () {
return Product::get();
});
return view('products', compact('products'));
}
Это приводит к отсутствию обращений к базе данных: результаты берутся из кэша.
Кэширование более сложных результатов
Что, если вы хотите кэшировать по какому-то условию, например по категории?
Давайте добавим условие к предыдущему примеру: фильтровать по категориям и кэшировать эти результаты на 60 минут, сохраняя при этом исходный список нетронутым.
app/Http/Controllers/ProductsController.php:
use Illuminate\Support\Facades\Cache;
use Illuminate\Http\Request;
// ...
public function index(Request $request)
{
if ($request->has('category')) {
$products = Cache::remember('products_list_' . $request->input('category'), 60 * 60, function () use ($request) {
return Product::where('category', $request->input('category'))->get();
});
} else {
$products = Cache::remember('products_list', 60 * 60, function () {
return Product::get();
});
}
return view('products', compact('products'));
}
Как видите, имя ключа становится 'products_list_' . $request->input('category')
.
Таким образом, мы будем иметь разные ключи кэша для каждой категории и не будем переопределять product_list
заданный по умолчанию.
Удаление кэшированных результатов
Для удаления кэшированных результатов вызовите функцию Cache::forget()
с ключом, который нужно удалить.
app/Http/Controllers/ProductsController.php:
use Illuminate\Support\Facades\Cache;
// ...
Cache::forget('products_list');
Удаление результатов кэширования после извлечения данных
Иногда вы знаете, что данные необходимо обновить при следующем запросе пользователя. Используйте pull
для извлечения и хранения данных, а затем очистите их.
app/Http/Controllers/ProductsController.php:
use Illuminate\Support\Facades\Cache;
// ...
public function index()
{
$products = Cache::pull('products_list', 60 * 60, function () {
return Product::get();
});
return view('products', compact('products'));
}
Автоматическая очистка кэша при изменении модели Eloquent
Имейте в виду: при кэшировании будет извлечена последняя версия модели из кэша, даже если её обновили в базе данных. Итак, если хотите обновить кэш, удалите его вручную или используйте Наблюдателей модели, чтобы они сделали это за вас.
Например, ваш код может выглядеть так:
app/Models/Product.php:
use Illuminate\Support\Facades\Cache;
// ...
protected static function boot()
{
parent::boot();
static::created(function () {
Cache::forget('products_list');
});
static::updated(function () {
Cache::forget('products_list');
});
}