Laravelのモデル層でデータをキャッシュするにはどうすればよいですか?

Guanhui
リリース: 2020-06-11 09:21:07
転載
3240 人が閲覧しました

Laravelのモデル層でデータをキャッシュするにはどうすればよいですか?

モデル データを以前にキャッシュしたことがあるかもしれませんが、動的ログ モデルを使用したより複雑な Laravel モデル キャッシュ手法を紹介します。これは、RailsCasts で学習した手法から始めました。

モデルの一意のキャッシュ キーを使用すると、モデル (または関連モデル) が更新されたときに自動的に更新 (およびキャッシュの無効化) されるプロパティと関連付けをモデルにキャッシュできます。利点の 1 つは、キャッシュされたデータへのアクセスが高速化されることです。キャッシュされたデータは、単一のコントローラー メソッドではなくモデル上にあるため、再利用可能です。

これがこのテクノロジーの重要なポイントです:

多くのコメント記事モデルがあると仮定し、次の Laravel ブレード テンプレートを指定すると、次のように /article/:id ルートにアクセスできます。コメント数を取得します:

<h3>$article->comments->count() {{ str_plural(&#39;Comment&#39;, $article->comments->count())</h3>
ログイン後にコピー

コメント数をコントローラーでキャッシュできますが、キャッシュする必要があるワンタイム クエリやデータが複数ある場合、コントローラーが非常に肥大化し、見苦しくなる可能性があります。 。コントローラーを使用してキャッシュされたデータにアクセスするのもあまり便利ではありません。

記事が更新されたときにのみデータベースにアクセスするテンプレートを構築でき、モデルにアクセスするすべてのコードでキャッシュされた値を取得できます。

<h3>$article->cached_comments_count {{ str_plural(&#39;Comment&#39;, $article->cached_comments_count)</h3>
ログイン後にコピー

モデル アクセサーを使用すると、次のことができます。キャッシュ 前回の記事更新に基づいたコメント数。

では、コメントが追加または削除されたときに、記事の updated_at 列の値をどのように更新すればよいでしょうか?

最初にタッチ方法を入力して確認してください。

モデルのトリガー

モデルの touch() メソッドを使用して、記事の updated_at 列の値を更新できます:

$ phpArtisan tinker

>>> $article = \App\Article::first();
=> App\Article {#746
     id: 1,
     title: "Hello World",
     body: "The Body",
     created_at: "2018-01-11 05:16:51",
     updated_at: "2018-01-11 05:51:07",
   }
>>> $article->updated_at->timestamp
=> 1515649867
>>> $article->touch();
=> true
>>> $article->updated_at->timestamp
=> 1515650910
ログイン後にコピー

更新されたタイムスタンプ値を使用してキャッシュを無効にすることができます。しかし、コメントを追加または削除するときに、記事の updated_at フィールドの変更をトリガーするにはどうすればよいでしょうか?

Eloquent モデルには $touches と呼ばれるプロパティがあります。コメント モデルは次のようになります。

<?php
namespace App;
use App\Article;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
    protected $guarded = [];
    protected $touches = [&#39;article&#39;];
    public function article()
    {
        return $this->belongsTo(Article::class);
    }
}
ログイン後にコピー
ログイン後にコピー

ここの $touches プロパティは、コメントの作成、保存、削除時に「トリガー」を引き起こす関連情報を含む配列です。

キャッシュされたプロパティ

$article->cached_comments_count アクセサーに戻りましょう。このメソッドの実装は、App\Article モデルでは次のようになります:

public function getCachedCommentsCountAttribute()
{
    return Cache::remember($this->cacheKey() . &#39;:comments_count&#39;, 15, function () {
        return $this->comments->count();
    });
}
ログイン後にコピー

一意のキー値のcacheKey() メソッドを使用してモデルを 15 分間キャッシュし、その後単にコメント カウント値を返します。クロージャーメソッドで。

キャッシュ メカニズムのガベージ コレクション戦略に基づいて、期限切れのキー値を削除するために Cache::rememberForever() メソッドも使用することに注意してください。 15 分ごとのキャッシュ更新間隔の間、ほとんどの時間でキャッシュのヒット率が最高になるようにタイマーを設定しました。

cacheKey() メソッドはモデルの一意のキー値を使用する必要があり、モデルが更新されると対応するキャッシュは無効になります。以下は私のcacheKey実装コードです:

public function cacheKey()
{
    return sprintf(
        "%s/%s-%s",
        $this->getTable(),
        $this->getKey(),
        $this->updated_at->timestamp
    );
}
ログイン後にコピー

モデルのcacheKey()メソッドの出力結果の例は、次の文字列情報を返す場合があります:

articles/1-1515650910
ログイン後にコピー

このキー値はテーブル名とモデルIDで構成されます現在の updated_at の値とタイムスタンプ値。このモデルをトリガーすると、タイムスタンプ値が更新され、それに応じてモデル キャッシュが無効になります。

記事モデルの完全なコードは次のとおりです:

<?php
namespace App;
use App\Comment;
use Illuminate\Support\Facades\Cache;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
    public function cacheKey()
    {
        return sprintf(
            "%s/%s-%s",
            $this->getTable(),
            $this->getKey(),
            $this->updated_at->timestamp
        );
    }
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
    public function getCachedCommentsCountAttribute()
    {
        return Cache::remember($this->cacheKey() . &#39;:comments_count&#39;, 15, function () {
            return $this->comments->count();
        });
    }
}
ログイン後にコピー

次に、関連するコメント モデル:

<?php
namespace App;
use App\Article;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
    protected $guarded = [];
    protected $touches = [&#39;article&#39;];
    public function article()
    {
        return $this->belongsTo(Article::class);
    }
}
ログイン後にコピー
ログイン後にコピー

次に何をしますか?

単純なコメント数をキャッシュする方法を説明しましたが、すべてのコメントをキャッシュする場合はどうすればよいでしょうか?

public function getCachedCommentsAttribute()
{
    return Cache::remember($this->cacheKey() . &#39;:comments&#39;, 15, function () {
        return $this->comments;
    });
}
ログイン後にコピー

モデルをシリアル化する代わりにコメントを配列に変換して、フロントエンドのデータへの単純な配列アクセスのみを許可することもできます:

public function getCachedCommentsAttribute()
{
    return Cache::remember($this->cacheKey() . &#39;:comments&#39;, 15, function () {
        return $this->comments->toArray();
    });
}
ログイン後にコピー

最後に、cacheKey を定義しました。 Article モデル () メソッド内にありますが、このメソッドを ProvidesModelCacheKey というトレイトを介して定義して、複合モデルで使用したり、基本モデルのすべてのモデル拡張機能のメソッドを定義したりすることもできます。さらに、cacheKey() メソッドを実装するモデルのコントラクト (インターフェイス) を使用することもできます。

推奨チュートリアル: 「PHP チュートリアル」「Laravel

以上がLaravelのモデル層でデータをキャッシュするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:learnku.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!