laravel数据库数据代码(在Laravel的Model层做数据缓存的实现)
laravel数据库数据代码
在Laravel的Model层做数据缓存的实现您在此之前可能就已经缓存过模型数据,但是我将向您展示一个使用动态记录模型的更精细的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
。下面是我们的评论模型的大概样子:
|
<?php namespace App; use App\Article; use Illuminate\Database\Eloquent\Model; class Comment extends Model { protected $guarded = []; protected $touches = [ 'article' ]; public function article() { return $this ->belongsTo(Article:: class ); } } |
这里的 $touches
属性是个数组,包含了在评论的创建、保存和删除时会引起“触发”的关联信息。
缓存的属性
我们先回到 $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
模型的完整代码:
|
<?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() . ':comments_count' , 15, function () { return $this ->comments-> count (); }); } } |
然后是关联的 Comment
模型:
|
<?php namespace App; use App\Article; use Illuminate\Database\Eloquent\Model; class Comment extends Model { protected $guarded = []; protected $touches = [ 'article' ]; public function article() { return $this ->belongsTo(Article:: class ); } } |
接下来做什么?
我已经向你展示了如何缓存一个简单的评论计数,但是如何缓存所有的评论呢?
|
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()
方法的模型使用使用契约(接口)。
我希望你已经发现这个简单的技术是十分有用的!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持开心学习网。
原文链接:https://segmentfault.com/a/1190000020499271
- laravel关闭错误提示(解决laravel session失效的问题)
- laravel的验证规则(解决在Laravel 中处理OPTIONS请求的问题)
- laravel框架配置(Laravel框架实现多数据库连接操作详解)
- phplaravel怎么优化(laravel执行php artisan migrate报错的解决方法)
- laravel5.1获取数据(laravel5表单唯一验证的实例代码)
- laravel提取数据库的字段(Laravel创建数据库表结构的例子)
- laravel数据表配置(laravel实现按月或天或小时统计mysql数据的方法)
- laravel常用的辅助函数介绍(Laravel框架表单验证操作实例分析)
- laravel如何设置默认模块(Laravel框架控制器的middleware中间件用法分析)
- laravel定时脚本(laravel实现按时间日期进行分组统计方法示例)
- laravel认证系统(Laravel框架Auth用户认证操作实例分析)
- laravel命令行与可选项(Laravel6.0.4中将添加计划任务事件的方法步骤)
- php框架laravel使用(laravel5环境隐藏index.php后缀apache的方法)
- laravel命令大全详解(Laravel框架中缓存的使用方法分析)
- laravel增删改查接口(laravel-admin 实现给grid的列添加行数序号的方法)
- laravel测试重连数据库(Laravel关系模型指定条件查询方法)
- 刘韬涛丁子贺小品《根治低头族》台词剧本(刘韬涛丁子贺小品根治低头族台词剧本)
- 看完《夺冠》,黄渤的演技我实在夸不起来,彭昱畅反令人惊喜(黄渤的演技我实在夸不起来)
- 黄渤泪目 我的痴呆父亲,我内心永远的痛(黄渤泪目我的痴呆父亲)
- 蒜苔和鱿鱼尾巴一起炒,味道特别棒,又脆又嫩,有滋又有味(蒜苔和鱿鱼尾巴一起炒)
- 鱿鱼炒蒜苔不是黑暗料理,这样做清香扑鼻,鲜美脆嫩,开胃又下饭(鱿鱼炒蒜苔不是黑暗料理)
- 蒜苔炒鱿鱼(蒜苔炒鱿鱼)
热门推荐
- docker是k8s 编排必备容器工具(Docker部署ELK7.3.0日志收集服务最佳实践)
- Docker 部署单机版 Pulsar 和集群架构 Redis(开发神器)的方法(Docker 部署单机版 Pulsar 和集群架构 Redis开发神器的方法)
- dedecms登录功能(DEDECMS织梦远程附件服务器设置详解)
- 查看docker 镜像大小(详解六种减小Docker镜像大小的方法)
- 创建jsp时如何默认生成的是utf-8(js判断文件是否为utf-8编码的方法)
- html5显示中心代码(HTML5中的Web Notification桌面通知功能的实现方法)
- djangoapi接口开发(Django使用AJAX调用自己写的API接口的方法)
- iisweb服务器的启动与配置(win7 iis配置怎么配置 Win7配置IIS服务器图文教程)
- Uncaught RangeError: Maximum call stack size exceeded的常见原因
- 微信小程序实现自动定位(微信小程序实现锚点定位功能的方法实例)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9