无为清净楼资源网 Design By www.qnjia.com

您在此之前可能就已经缓存过模型数据,但是我将向您展示一个使用动态记录模型的更精细的Laravel模型缓存技术,这是我一开始在 RailsCasts学习到的技术。

使用模型的唯一缓存键,您可以缓存模型(或关联模型)更新时自动更新(以及缓存失效)的模型上的属性和关联,一个好处是访问缓存的数据比在控制器中缓存的数据更具可复用性,因为它在模型上而不是在单个控制器方法中。

这是这个技术的要点:

假设你有很多个 Comment 的 Article 模型,给定下面的Laravel blade 模板,你就可以像下面这样访问 /article/:id 路由时得到评论的数量:

<h3>$article->comments->count() {{ str_plural('Comment', $article->comments->count())</h3>

您可以在控制器中缓存评论的计数,但是当您有多个需要缓存的一次性查询和数据时,控制器会变得非常臃肿难看。使用控制器,访问缓存的数据也不是很方便。

我们可以构建一个模板,它仅在文章更新时访问数据库,并且访问该模型的所有代码都可以获取缓存值:

<h3>$article->cached_comments_count {{ str_plural('Comment', $article->cached_comments_count)</h3>

通过使用模型访问器,我们可以缓存基于最后一次文章更新的评论计数值。

因此,在评论新增或删除时我们该怎么更新文章的 updated_at 列值呢?

先进入 touch 方法看看。

模型的触发

可以通过使用模型的 touch() 方法来更新文章的 updated_at 列值:

$ php artisan 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

我们可以用更新的 timestamp 值使缓存失效。不过在新增或删除一个评论时,我们怎么触发修改文章的 updated_at 字段呢?

碰巧 Eloquent 模型中有一个属性就叫 $touches 。下面是我们的评论模型的大概样子:

<"color: #ff0000">缓存的属性

我们先回到 $article->cached_comments_count 访问器。该方法的实现可能象 App\Article 模型中的样子:

public function getCachedCommentsCountAttribute()
{
  return Cache::remember($this->cacheKey() . ':comments_count', 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 的 timestamp 值组成。一旦我们触发这个模型,timestamp 值就会更新,并且我们的模型缓存就会相应地失效。

以下是 Article 模型的完整代码:

<"%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() . ':comments_count', 15, function () {
      return $this->comments->count();
    });
  }
}

然后是关联的 Comment 模型:

<"color: #ff0000">接下来做什么"htmlcode">
public function getCachedCommentsAttribute()
{
  return Cache::remember($this->cacheKey() . ':comments', 15, function () {
    return $this->comments;
  });
}

你也可以选择将评论转换为数组替代序列化模型,只允许在前端对数据进行简单的数组访问:

public function getCachedCommentsAttribute()
{
  return Cache::remember($this->cacheKey() . ':comments', 15, function () {
    return $this->comments->toArray();
  });
}

最后,  我在 Article 模型中定义了cacheKey()方法,但是你可能想要通过一个名为 ProvidesModelCacheKey的trait来定义这个方法以便你可以在复合模型中使用或者在一个基础模型中定义所有模型扩展的方法。 你甚至可能想要为实现cacheKey() 方法的模型使用使用契约(接口)。

我希望你已经发现这个简单的技术是十分有用的!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

标签:
Laravel,Model层,数据缓存,Laravel,数据缓存

无为清净楼资源网 Design By www.qnjia.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
无为清净楼资源网 Design By www.qnjia.com

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。