Yii2 的 ActiveRecord 浅析 [ 2.0 版本 ]
发现一直到 Yii 的 AR 了解很少,称这几天有空,仔细了解了一下,不足之处还望多多指点。
AR三层
AR 的实现比较复杂,而且实现细节很多,为了大家了解,我按照官方资料,将 AR 分为三层介绍,并且尽量不涉及细节,因为一深入细节就容易一叶障目不见泰山。
AR 分的三层依次是DAO(数据访问层),Query Builder(查询构建器),然后就是 AR 。可能大家会问模型呢?附上此继承图,去掉了很多不必要的细节。
从图中可以看出。AR 继承了 Model 和 Query Builder(这是一个层,并不是一个类) 两个类(由于PHP只能实现单继承,所以 AR 只继承了 Model ,而Query Builder 是通过其他方式得到的,为了便于理解,暂时先理解为继承就行。),其中 Model 实现了表单验证、场景等一系列功能。而 Query Builder 这个则负责进行数据库操作,AR 只是将两个类的功能组合到一起了(当然也做了一些修改,并添加了一些新功能)。
接下来详细介绍每个东西。
DAO层(官方DAO介绍)
Yii 包含了一个建立在 PHP PDO 之上的数据访问层 (DAO)。DAO为不同的数据库提供了一套统一的API。 DAO提供了简单高效的SQL查询,可以用在与数据库交互的各个地方。
摘自 Yii 权威指南,上面指出了 DAO 做的两件事:
- 一是处理不同数据库的差别,提供一套统一的 API ,
- 二是提供了简单高效的 SQL 查询。
处理不同数据库这点暂时未研究,大家可以自己去看看。
关于执行SQL则是通过 yii\db\Command
这个类实现的,大家可以自己去看看这个类,然后结合 Yii 权威指南的介绍。
Query Builder(查询构建器)官方QB介绍
查询构建器建立在 Database Access Objects 基础之上,可让你创建 程序化的、DBMS无关的SQL语句。相比于原生的SQL语句,查询构建器可以帮你 写出可读性更强的SQL相关的代码,并生成安全性更强的SQL语句。
查询构建器实现了面向对象的查询方法,在 AR 中执行的大部分方法都是执行这个类的方法。这个类就是\yii\db\Query
类
简单说一下类继承和使用关系。看看\yii\db\Query
中两个简单且常用的方法。
public function all($db = null)
{
$rows = $this->createCommand($db)->queryAll();
return $this->populate($rows);
}
public function one($db = null)
{
return $this->createCommand($db)->queryOne();
}
两个方法都调用了createCommand()
方法
public function createCommand($db = null)
{
if ($db === null) {
$db = Yii::$app->getDb();
}
list ($sql, $params) = $db->getQueryBuilder()->build($this);
return $db->createCommand($sql, $params);
}
首先Yii::$app->getDb()
获得数据库链接,返回的是yii\db\Connection
实例。接着$db->getQueryBuilder()->build($this);
调用getQueryBuilder()
方法,返回一个yii\db\QueryBuilder
实例,调用build()
,传入\yii\db\Query
,生成相应的SQL语句,然后$db->createCommand($sql, $params)
获得 yii\db\Command
实例并执行SQL语句。
总接一下。涉及四个类:
yii\db\Connection
建立数据库链接,并有生成yii\db\QueryBuilder
, yii\db\Command
等一系列方法。
yii\db\Command
执行SQL语句,拥有一些简单的查询数据库方法。
\yii\db\Query
包含大量的面向对象操作数据库方法。工作原理是,拥有很多不同的属性,执行不同的方法会对属性做修改。
yii\db\QueryBuilder
生成SQL语句,传入\yii\db\Query
对象,根据该对象的属性,生成动态的SQL语句。
模型 Model
直接找到\yii\base\Model
类,该类就是 Yii 中的模型类。里面如下功能的实现。
- 属性: 代表可像普通类属性或数组 一样被访问的业务数据;
- 属性标签: 指定属性显示出来的标签;
- 块赋值: 支持一步给许多属性赋值;
- 验证规则: 确保输入数据符合所申明的验证规则;
- 数据导出: 允许模型数据导出为自定义格式的数组。
不做具体分析,大家自行查看。
AR层
AR 层也不做深入探究。 AR 层主要类就两个,一个是\yii\db\ActiveRecord
,另一个是\yii\db\ActiveQuery
。
其中\yii\db\ActiveRecord
j继承了\yii\base\Model
,并覆盖了一些函数,以便实现 Model 的一些功能在数据库中的实现。比如将数据库字段查询出来做属性等等。另外还提供了一些封装的数据库访问方法,如find()
等.
\yii\db\ActiveQuery
提供了更高级的SQL查询方法,继承\yii\db\Query
,原理同上。
总结
本想深入进去学习一下,当面对十几个类,上百个方法,还是没能深入下去。惭愧惭愧!只能得到这些表层东西,供君一读。
石头杨
最后登录:2021-01-23
在线时长:13小时6分
- 粉丝39
- 金钱325
- 威望120
- 积分1655
共 3 条评论
“由于PHP只能实现单继承” 这句话有问题
不严谨而已 php可以通过interface 接口方式实现多继承
ActiveRecord这东西确实很多时候很好用,但是,如果你的表的数据量大了,可不要使用它,它返回的对象还有嵌套了其它类的地方,太大了。
我觉得写的挺好啊