前段时间发表了一篇文章 面向对象的一小步:添加 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()

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

最新文章

  1. H3 BPM让天下没有难用的流程之功能介绍
  2. jeecg bootstrap修改单列模版
  3. JFreechart 在linux下不显示及中文乱码问题
  4. __autoload的小tip
  5. eclipse几个注意的地方
  6. [转]微服务(Microservice)那点事
  7. Longest Substring with At Most K Distinct Characters
  8. Java对象的序列化和反序列化实践
  9. 关于Class.forName("oracle.jdbc.driver.OracleDriver");报ClassNotFoundException 的异常
  10. Learning WCF Chapter1 Exposing Multiple Service Endpoints
  11. 第一讲 一个简单的Qt程序分析
  12. Andy Williams 《Love Story》
  13. DOM操作表格——HTML DOM
  14. PostCSS 基本用法
  15. SQL Server 异常解决:语句被终止。完成执行语句前已用完最大递归 100。
  16. python -- ajax数组传递和后台接收
  17. Jsp 国际化访问首页选择展示不同字体小例子
  18. 网络对抗技术 2017-2018-2 20152515 Exp2 后门原理与实践
  19. Linux awk工具简单学习记录
  20. golang defer的使用

热门文章

  1. djiango的模板语言(template)
  2. [Objective-C语言教程]简介(1)
  3. asp.net core系列 49 Identity 授权(上)
  4. 第一章.java&golang的区别之:闭包
  5. 『备注』GDI+ 绘制文本有锯齿,透明背景文本绘制
  6. 结合JDK源码看设计模式——单例模式
  7. 【原】无脑操作:TypeScript环境搭建
  8. Microsoft Edge浏览器下载文件乱码修复方法(二)
  9. winform 实现类似于TrackBar的自定义滑动条,功能更全
  10. Spark学习之路 (一)Spark初识