Laravel: Кэширование Eloquent — Что нужно знать

Источник: «Eloquent Caching: Main Things You Need To Know»
При работе с большими набора данных, которые сложно получить или они редко изменяются, для снижения нагрузки на базу данных мы можем использовать кэширование.

Для этого используется класс 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'));
}

Это приводит к отсутствию обращений к базе данных: результаты берутся из кэша.

Кэширование результатов Eloquent модели Laravel

Кэширование более сложных результатов

Что, если вы хотите кэшировать по какому-то условию, например по категории?

Давайте добавим условие к предыдущему примеру: фильтровать по категориям и кэшировать эти результаты на 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');
});
}

Дополнительные материалы

Предыдущая Статья

PHP: Что такое Интерфейс

Следующая Статья

Laravel: Рекомендации на 2023 год. Полное руководство