引言

原则上代码写一次,处处是引用,不需要大量的冗余代码,这是一种趋势,也是提高代码健壮性的努力方向。 laravel模型为我们提供了一层数据库操作层,将数据交互独立出来。

但是久而久之,随着项目的需求不断扩大,最常用的查询操作,同样会有大量的冗余代码。

本文就来讲讲,连模型的自我瘦身,缩减模型的代码。

全局作用域

假设有些数据库查询操作,无论是在控制器内,或者在模板文件内,或者命令行方法内,都有重复的使用需求,要是在模型内有一个公用的方法,默认就加上这些筛选条件,就可以显著减少代码量了。

比如有一个查询条件:

$publishedEvents = Event::where('published', '=', 1)->get();

上述代码最后生成的SQL语句如下:

SELECT * FROM events WHERE `published` = 1;

如果条件 published = 1 在默认的情况下需要开启,我们可以使用laravel模型的 全局作用域 方式为所有查询追加上这个条件。

在模型文件 Event 内头部引入下述类:

use IlluminateDatabaseEloquentModel;use IlluminateDatabaseEloquentBuilder;

在模型类内部,手动实现 boot 方法:

protected static function boot(){    parent::boot();    static::addGlobalScope('published', function (Builder $builder) {        $builder->where('published', '=', 1);    });}

这样SQL语句 where published = 1 就会追加到所有的模型查询方法内,只要是创建生成了 QueryBuilder 对象的,都会附加上此约束语句。

那有些读者可能要问了:“如果我不想要这个约束语句,岂不是连模型也永不了了?

那哪儿能呢!不过就是QueryBuilder的一个属性数组的一个元素而已,手动移除就行了,这样特例问题就解决了。

$events = Event::withoutGlobalScopes()->get();

看到了吧,追加上很简单,移除更简单。

本地作用域

接上一节的 withoutGlobalScope 要每次手动屏蔽的方式不同,有时候使用有局限的作用域更能解决问题。所以,本地作用域 应运而生,专门用于某个模型文件的方法,手动调用的时候就起作用,不调用就不会主动追加。

而声明一个本地作用域,只要遵循laravel的语法规定即可,如下示例:

public function scopePublished($query){    return $query->where('published', 1);}

只需要声明一个以 scope 为首的小驼峰命名的函数方法即可,并返回一个 QueryBuilder 对象实例。调用的时候要手动追加上:

$events = Event::published()->get();

其中 published()方法就是映射到 scopePublished 方法。

上面的演示代码,没有接收用户输入,下面演示一下带参的传递方式。比如有这样一个查询需求:

$events = Event::where('zip', $zipCode)->get();

使用本地作用域实现出来:

public function scopeZip($query, $zip){    return $query->where('zip', $zip);}

按照位置传入即可。使用的使用,直接传入:

$zip = '43016';$events = Event::zip($zip)->get();

这样就完成了本地作用域的使用,是不是很直观。

既然本地作用域返回的是 QueryBuilder 实例,那么自然就可以链式调用本地作用域的方法,和 QueryBuilder 的方法。我们再声明一个本地作用域方法:

public function scopeAttendees($query, $maximum){    return $query->where('max_attendees', $maximum);}

现在把上述两个方法串联使用:

$events = Event::zip(43016)->attendees(2)->get();

生成的SQL语句也符合预期:

SELECT * FROM events WHERE zip = '43016' and max_attendees = '2';

写在最后

本期我们又旧事重提,把laravel模型的作用域设计方法拿出来温习了一下。讲述了两个方法:

  • 全局作用域:全局起作用,需要手动移除;
  • 本地作用域:只有手动调用起作用,可链式使用;

这样的设计模式可以很大程度上节约查询代码,但是对于维护,需要同等熟悉的开发者彼此遵循开发规范,写出可维护的代码。

Happy coding :-)

我是@程序员小助手,专注编程知识,圈子动态的IT领域原创作者

语句作用_3分钟短文:Laravel模型作用域,为你“节省”更多代码相关推荐

  1. sql查询无结果返回空_3分钟短文 | Laravel 查询结果检查是不是空,5个方法你别用错...

    引言 Laravel 提供了 Eloquent ORM 对象用于操作数据库,将其进行抽象方便操作. 因为设计的灵活度,大家在使用Model查询数据集的时候,会面临结果为空,记录不存在的问题, 那么如何 ...

  2. mvc 前段定义变量_3分钟短文 | Laravel blade模板里优雅地定义PHP变量

    引言 Laravel秉持MVC的设计理念,在V = view 中放置视图相关的内容.特别是 blade 模板引擎带来了很强大的解析方式. 与传统的PHP与HTML写作一团方式不容,Blade 使用特定 ...

  3. laravel $request 多维数组取值_3分钟短文 | Laravel 内3种数据校验的写法,你喜欢哪一个?...

    引言 web应用程序公开访问几乎没有不带用户交互的,难免要接收用户输入的奇奇怪怪的东西.对于后端程序,必须对输入的内容进行有效性过滤. 这就是本文的重点,说一说laravel中输入请求的校验. 学习时 ...

  4. 拼装sql_3分钟短文 | Laravel复杂SQL超多WHERE子句,本地作用域你没用过

    引言 使用框架就是为了方便把注意力集中在逻辑上,而不用关心与数据库操作的方方面面.Laravel提供的 eloquent orm 使用面向对象的方式封装了PDO数据库操作,使用起来非常方便,对于复杂的 ...

  5. laravel artisan 后台运行_3分钟短文:Laravel用户自定义命令行简明教程

    引言 完成一个功能需求,有时候并不需要一个界面UI,比如定时任务,后台任务, 对于这类任务往往比较耗时,在一个web页面生命周期内,要拖的很久.这时候我们 需要将其放在后台交给操作系统执行. 本期说一 ...

  6. laravel $request 多维数组取值_3分钟短文:Laravel的“南天门”,过滤掉七七八八的数据...

    引言 上一章我们教会大家如何从用户表单内正确地获取数据,可是没有讲,获取到的数据到底有啥用,或者说,有的用户提交的数据压根儿就没正经填,那些错乱无效的数据,如果直接放到数据库,纯粹是对数据库的污染. ...

  7. 安卓应用用户数据_3分钟短文:Laravel应用跟用户打交道,就从拿到他们的数据开始!...

    引言 本来讲完路由和控制器,应该接着讲一讲视图的,但是鉴于视图的功能实在太枯燥,况且是前端页面,免不了写一些js和css.而laravel是偏重后端的,所以为了给后端的开发同学缓冲的时间,我们跳过视图 ...

  8. request用法_3分钟短文:说说Laravel页面会话之间的数据保存Session用法

    引言 我们知HTTP请求是没有状态的,两个请求之间没有直接的关联关系.但大多数情况下, 我们需要保持用户的会话间数据的连续性,这时,为了数据安全起见, 有必要在服务器上临时存储一些上下文数据了. 这就 ...

  9. html尾部代码_3分钟短文:Laravel Form,让你不再写 HTML 的好“库”

    引言 作为后端工程师的你,是不是面对一堆JS,CSS感觉无比抓狂.如果能摆脱大量的冗余的HTML代码块, 那该多好啊.laravel作为扩展性极强的框架,自然是为广大后端开发者赋能. 本文我们讲一个简 ...

最新文章

  1. 2021-10-27 我与地坛
  2. 【学术】直博和读完硕士再读博,在能力上的差距有多大?
  3. 删掉java影响什么_java带来的影响
  4. jquery拓展插件开发
  5. 自然语言处理中的自注意力机制(Self-Attention Mechanism)
  6. Netbeans自定义mode
  7. 部署在SAP ABAP服务器上的SAP UI5应用的JavaScript文件,是如何被SAP UI5 repository handler处理的
  8. Viewport3D 类Viewport3D 类Viewport3D 类
  9. CUBRID学习笔记 46 PREPARED set Do
  10. 老实说,WPF对自由开发者与小微型团体来说就是个毒瘤!
  11. Win7 IIS7 HTTP 错误 404.2 - Not Found解决方法
  12. POJ-1328(Greedy,Vector,Sort,Iterator)
  13. Php sql server2005,phpmssqlserver2005数据库连接类
  14. datatable的数据进行组内排序_极客算法训练笔记(六),十大经典排序之希尔排序,快速排序...
  15. CentOS8-Tomcat7安装并设置开机自启动
  16. 用Html制作网页简单例子
  17. java全栈_java全栈的知识技能
  18. VMware网络配置基础
  19. python如何编写温度转换_Python温度转换实例分析
  20. python-华为路由器交换机批量处理ip与mac绑定

热门文章

  1. javaheapspace解决方案_高手总结的9种 OOM 常见原因及解决方案
  2. php 中文键名 问题,PHP中使用asort进行中文排序失效的问题处理
  3. 微服务的好处与弊端_在云原生时代,就一定要用微服务吗?
  4. xenserver 虚拟机扩容lvm磁盘分区的方法_Linux磁盘扩容
  5. 搜狗输入法电脑版_搜狗输入法就是垃圾!!!大大的垃圾!
  6. Android中网络请求创建单个线程池的方法
  7. html5实现圆圈里带一个三角形,CSS制作箭头图标代码(圆,三角形,椭圆)c
  8. 零基础学习 Python 之文件
  9. logstash的使用教程
  10. 第10章 springboot是什么