darkghosthunter/rememberable-query

此包已废弃,不再维护。作者建议使用laragear/cache-query包。

记住查询结果仅用一行表达

v3.1.1 2022-02-16 18:38 UTC

This package is auto-updated.

Last update: 2022-02-16 18:39:18 UTC


README

记住查询

使用一种方法记住查询结果。是的,只有一种。

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

要求

  • PHP 8.0
  • Laravel 8.x

安装

您可以通过composer安装此包

composer require darkghosthunter/rememberable-query

使用方法

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

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哈希,这避免了与其他查询的冲突,同时保持了缓存键的简短。

您可以使用任何字符串,但建议追加query|以避免与您的应用程序中的其他缓存键冲突。

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

或者,您可以使用自定义缓存存储来记住查询。

自定义缓存存储

在某些情况下,使用应用程序的默认缓存可能不如数据库性能好,或者可能与其他键冲突。您可以通过设置第三个参数或命名参数使用任何其他缓存存储。

Article::latest('published_at')->take(10)->remember(store: 'redis')->get();

缓存锁(数据竞争)

在多个进程上,查询可能会被多次执行,直到第一个进程能够将结果存储到缓存中,尤其是在这些操作需要超过1秒的情况下。为了避免这种情况,设置wait参数以指定保持锁的时间(秒数)。

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

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

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

幂等查询

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

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

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

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

之后的查询执行将不会执行,直到缓存过期,因此在上面的例子中,我们意外地创建了一个“唯一浏览量”机制。

操作是可交换的

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

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

User::whereName('Joe')->whereAge(20)->remember()->first();
// Cache key: "query|/XreUO1yaZ4BzH2W6LtBSA=="

User::whereAge(20)->whereName('Joe')->remember()->first();
// Cache key: "query|muDJevbVppCsTFcdeZBxsA=="

为了确保你在类似的查询上访问相同的缓存,请使用自定义缓存键。有了这个,所有使用相同键的查询将共享相同的缓存结果

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

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

$joe = Cache::get('query|find_joe');

许可

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