前段时间发表了一篇文章 面向对象的一小步:添加 ActiveRecord 的 Scope 功能 提到一种更加友好的方式做数据库查询。经小伙伴的建议,在满足同样条件下,可以有更为简洁的封装方法。

这需要用到重载ActiveQuery方法,在通过gii建数据模型model时,可以勾选"Generate ActiveQuery"这么一项自动生成。

例如,在生成Student Model时,可以自动生成StudentQuery

class StudentsQuery extends \yii\db\ActiveQuery
{
/**
* {@inheritdoc}
*
* @return TbStudents[]|array
*/
public function all($db = null)
{
return parent::all($db);
} /**
* {@inheritdoc}
*
* @return TbStudents|array|null
*/
public function one($db = null)
{
return parent::one($db);
} //默认筛选已经审核通过的记录,当然,也可以自己定义$status
public function checked($status = 1)
{
return $this->where(['check_status' => $status]);
}
}

checked()方法里面有一条where条件,也可以添加多条。总之,这个checked方法可以随你定义, 封装一类现实应用常用的条件组合。

这样,我们便可以这样来查询:

Student::find()->checked()->where(...)->all();

那又如何满足checked方法的静态调用呢?

Student::checked()->where(...)->all();

这还得在Model里面重载__callStatic()方法。这个重载可写在一个如BaseModel的公共方法里面,以便大家调用。

public static function __callStatic($name, $arguments)
{
return static::find()->$name(...$arguments);
}

也更为简洁,同时也是一种透明操作。在StudentQuery中没有定义对应方法或者传参错误都会导致报错。

那么这是如何做到的?

因为在Student里面有这么一段:

public static function find()
{
return new StudentQuery(get_called_class());
}

可见在__callStatic中返回的static::find()其实就是一个StudentQuery的一个实例,然后在这个实例中去寻找checked方法。绕了个小圈子,重新回到了StudentQuery。道理非常简单。

现在我们同样可以实现两种友好的查询了:

Student::find()->checked()->where(...)->all();
Student::checked(2)->where(...)->all()

对代码简洁性和透明性的要求比较高的小伙伴,可以采用这种封装。

Scope 功能的改进的更多相关文章

  1. 一张图看懂ANSYS17.0 流体 新功能与改进

    一张图看懂ANSYS17.0 流体 新功能与改进   提交 我的留言 加载中 已留言   一张图看懂ANSYS17.0 流体 新功能与改进 原创2016-02-03ANSYS模拟在线模拟在线 模拟在线 ...

  2. 分享一下 Idea 的 scope 功能

    分享一下 Idea 的 scope 功能 事情的起因是我在使用 idea 的call hierarchy功能时,觉得它没有像find usage那样有排除功能,并且如果点击了展开全部,当代码中使用了某 ...

  3. vs2012远程调试功能的改进

    不知道大家有没有遇到过这种情况,刚开发完的程序,明明在本机能够好好的运行,可是部署到服务器过分发给用户时,总是出现莫名其妙的错误. 一时半会又看不出问题来,怎么办呢?难道只能在服务器或是客户电脑上装一 ...

  4. 面向对象的一小步:添加ActiveRecord的Scope功能

    问题场景 我们用Yii2的ActiveRecord功能非常的方便,假如我们有个Model叫Student,那么ActiveQuery可以通过这种方式轻便地获得: $query = Student::f ...

  5. Fedora Workstation 31众多功能得到改进

    导读 周一,Red Hat的桌面高级经理Christian F.K. Schaller分享了一篇博客文章,概述了Fedora Workstation 31的各种改进和特性.这些包括Wayland的改进 ...

  6. 对Web(Springboot + Vue)实现文件下载功能的改进

    此为 软件开发与创新 课程的作业 对已有项目(非本人)阅读分析 找出软件尚存缺陷 改进其软件做二次开发 整理成一份博客 原项目简介 本篇博客所分析的项目来自于 ジ绯色月下ぎ--vue+axios+sp ...

  7. C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 角色成员功能的改进支持公司加入到角色

    我们公司有1万多个网点,每个网点都可以看成是一个公司,公司对不同的网点有不同的策略,商业逻辑,每个网点的人员也都是在不断变化,全国有接近10万从业人员,当我们设计好业务逻辑程序后,不可能因为这些人员的 ...

  8. Yii2设计模式——静态工厂模式

    应用举例 yii\db\ActiveRecord //获取 Connection 实例 public static function getDb() { return Yii::$app->ge ...

  9. Yii2 设计模式——静态工厂模式

    应用举例 yii\db\ActiveRecord //获取 Connection 实例 public static function getDb() { return Yii::$app->ge ...

随机推荐

  1. 一份完整的阿里云 Redis 开发规范,值得收藏!

    来源:yq.aliyun.com/articles/531067 作者:付磊-起扬 本文主要介绍在使用阿里云Redis的开发规范,从下面几个方面进行说明. 键值设计 命令使用 客户端使用 相关工具 通 ...

  2. sau交流学习社区--看小说的lovebook一个无线端BS应用

    一.前言 loveBook爱上阅读,是一款webapp的读小说等书籍的并且阅读的应用.如果觉得可以,欢迎fork和star. 自己最近在追斗破苍穹电视剧,下班时候在地铁上总听到有人说,斗破苍穹书籍比电 ...

  3. C#读写EXCEL单元格的问题

    最近, 我在用C#开发一个EXCEL Add-In的时候,发现了一些害人不浅的坑,特来总结列举如下: 这里我读写EXCEL引用的是using Excel = Microsoft.Office.Inte ...

  4. JavaScript构造函数

    JavaScript不同于其他强类型语言,没有类的概念,但是它支持可以与实例共同使用特殊的Constructor构造器,使用new关键字创建新的实例,并告知JavaScript使用对象的内规则去定制这 ...

  5. TreeSet集合解析

    TreeSet是实现Set接口的实现类.所以它存储的值是唯一的,同时也可以对存储的值进行排序,排序用的是二叉树原理.所以要理解这个类,必须先简单理解一下什么是二叉树. 二叉树原理简析 假如有这么一个集 ...

  6. Unity_新手必懂知识点

    翻车了!!!一个小例子带你了解闭包.事故现场:场景:6个button,上方1个text.点击button,text会显示button上的数字.代码如下: //在unity里面赋值public List ...

  7. js初级入门

    javascript的数据类型 (symbol)一.原始数据类型 或 基本数据类型 6种 1,undefined (1,申明未赋值,2,函数没有返回值)2,null (空,不存在)3,number ( ...

  8. HTML入门知识汇总

    1. HTML认识 1.1 什么是HTML HTML是描述(制作)网页的语言,指的是超文本标记语言(Hyper Text Markup Language). 超文本:就是指页面内可以包含图片.链接.甚 ...

  9. DokuWiki的发现之旅

    ★DokuWiki介绍 Wiki是什么?是一种允许一群用户用简单的描述来创建和连接一组网页的社会计算系统,可以让人们在web的基础上对Wiki文本进行浏览.创建和更改,是一种人类的知识的网络系统,有助 ...

  10. 关于静态注册BroadcastReceiver接收不到广播的问题

    1.背景&解决方法 最近碰到一个需求,app监听特定的广播,接收到广播后启动自己再进行处理.需求很简单,静态注册就好,不过,在自测的时候遇到一个问题,app安装后没启动过的状态下,什么广播都收 ...