eusonlito/query-remember

此包已废弃,不再维护。未建议替代包。

记住 Laravel 查询构建器或 Eloquent 上的查询结果

0.0.3 2021-12-03 10:24 UTC

This package is auto-updated.

Last update: 2022-02-25 10:34:30 UTC


README

已迁移到新的仓库,以更高效的方式管理缓存: https://github.com/eusonlito/laravel-database-cache

Query Remember

基于 https://github.com/DarkGhostHunter/RememberableQuery,但增加了标签,并更专注于 Eloquent。

Articles::latest('published_at')->take(10)->remember()->get();

要求

  • PHP 8.0
  • Laravel 8.x

安装

您可以通过 composer 安装此包

composer require eusonlito/query-remember

php artisan vendor:publish --tag=eusonlito-query-remember

与 DarkGhostHunter/RememberableQuery 的差异

  • 使用 config/query-remember.php 配置文件可配置 TTL、驱动和启用。
  • 使用全局配置将数据库缓存按标签分组。
  • 模型可以使用 getCacheTaggetCacheTagSuffix 方法自定义模型标签。

用法

只需使用 remember() 方法在执行前记住查询结果。就是这样。该方法会自动将结果记住 60 秒。

如果您使用默认配置,此缓存将存储在 ['database', 'database|articles'] 标签中。

use Illuminate\Support\Facades\DB;
use App\Models\Article;

$database = DB::table('articles')->latest('published_at')->take(10)->remember()->get();

$eloquent = Article::latest('published_at')->take(10)->remember()->get();

下次调用 相同的 查询时,结果将从缓存中检索,而不是在数据库中运行 SQL 语句,即使结果是 nullfalse

如果构建了查询而不是执行它,remember() 将引发错误。

生存时间

默认情况下,查询会记住 60 秒,但您可以使用任何长度,例如 DatetimeDateInterval 或 Carbon 实例。

DB::table('articles')->latest('published_at')->take(10)->remember(60 * 60)->get();

Article::latest('published_at')->take(10)->remember(now()->addHour())->get();

自定义缓存键

自动生成的缓存键是 SQL 查询及其绑定的 BASE64-MD5 哈希,这避免了与其他查询发生冲突,同时保持了缓存键的简短。

如果您使用默认配置,此缓存将存储在 ['database', 'database|articles'] 标签中,键为 latest_articles

Article::latest('published_at')->take(10)->remember(30, 'latest_articles')->get();

缓存锁(数据竞争)

在多个进程的情况下,查询可能会在第一个进程能够将结果存储到缓存之前多次执行。为了避免这种情况,请设置 wait 参数以获取锁的时间(秒数)。

Article::latest('published_at')->take(200)->remember(wait: 5)->get();

第一个进程将获取给定秒数的锁,执行查询并将结果存储。下一个进程将等待缓存数据可用,然后从中检索结果。

如果您需要在多个进程中使用它,请直接使用 缓存锁

幂等查询

记住查询的原因是为了缓存从数据库中检索到的数据,您可以利用这一点来创建幂等查询。

例如,您可以使此查询每天只针对特定的用户ID执行一次。

$key = auth()->user()->getAuthIdentifier();

Article::whereKey(54)->remember(now()->addHour(), 'user:'.$key)->increment('unique_views');

在此查询的后续执行将不会执行,直到缓存过期,因此在上述示例中,我们意外地创建了一个“唯一视图”机制。

操作不是交换律的

更改构建方法的顺序将改变自动生成的缓存键哈希。即使它们在视觉上相同,语句的顺序也会使哈希完全不同。

例如,给定应用不同部分中的两个类似查询,这两个查询将不会共享相同的缓存结果

User::whereName('Joe')->whereAge(20)->remember()->first();
User::whereAge(20)->whereName('Joe')->remember()->first();

为确保您在类似的查询中触达相同的缓存,请使用自定义缓存键。有了这个,所有使用相同键的查询都将共享相同的缓存结果

User::whereName('Joe')->whereAge(20)->remember(60, 'find_joe')->first();
User::whereAge(20)->whereName('Joe')->remember(60, 'find_joe')->first();

这将允许您通过直接询问缓存来检索查询之外的数据。

$joe = Cache::tags(['database', 'database|users'])->get('find_joe');

请记住,您需要传递与缓存存储时相同的有序标签列表到tags方法。当XXX是查询相关的表名时,始终使用['database', 'database|XXX']

标签

此包使用两个不同的标签进行缓存(仅由redismemcached支持)

  • database是所有数据库缓存的全球标签。
  • database|XXXX是每个不同表的标签。表名将在模型上的getTable方法中设置,或在Query Builder上的from字符串中。

模型上的自定义标签

模型可以包括两个方法来创建自定义标签

  • getCacheTag将缓存标签与全局标签database以及由此方法返回的字符串相关联。
  • getCacheTagSuffix将缓存标签与全局标签database相关联,并将由此方法返回的字符串附加到database|之后。

清除缓存

您可以清除所有数据库缓存或仅清除与单个表相关的缓存

// Flush all database cache
Cache::tags('database')->flush();

// Flush only users table cache
Cache::tags('database|users')->flush();

许可证

MIT许可证(MIT)。请参阅许可证文件以获取更多信息。