石头杨 2016-12-30 19:32:47 11672次浏览 3条评论 5 5 0

发现一直到 Yii 的 AR 了解很少,称这几天有空,仔细了解了一下,不足之处还望多多指点。

AR三层

AR 的实现比较复杂,而且实现细节很多,为了大家了解,我按照官方资料,将 AR 分为三层介绍,并且尽量不涉及细节,因为一深入细节就容易一叶障目不见泰山。

AR 分的三层依次是DAO(数据访问层),Query Builder(查询构建器),然后就是 AR 。可能大家会问模型呢?附上此继承图,去掉了很多不必要的细节。

2016-12-30_193019.png

从图中可以看出。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\ActiveRecordj继承了\yii\base\Model,并覆盖了一些函数,以便实现 Model 的一些功能在数据库中的实现。比如将数据库字段查询出来做属性等等。另外还提供了一些封装的数据库访问方法,如find()等.

\yii\db\ActiveQuery提供了更高级的SQL查询方法,继承\yii\db\Query,原理同上。

总结

本想深入进去学习一下,当面对十几个类,上百个方法,还是没能深入下去。惭愧惭愧!只能得到这些表层东西,供君一读。

觉得很赞
  • 评论于 2017-01-12 09:45 举报

    “由于PHP只能实现单继承” 这句话有问题

    1 条回复
    评论于 2017-03-21 11:14 回复

    不严谨而已 php可以通过interface 接口方式实现多继承

    觉得很赞
  • 评论于 2019-11-13 18:21 举报

    ActiveRecord这东西确实很多时候很好用,但是,如果你的表的数据量大了,可不要使用它,它返回的对象还有嵌套了其它类的地方,太大了。

  • 评论于 2020-07-15 09:55 举报

    我觉得写的挺好啊

您需要登录后才可以评论。登录 | 立即注册