Active Record 模型是一种设计模式,用面向对象的方式抽象地访问数据库的模式。

  1. 在插入记录的时候,使用new关键字创建AR 模型对象;
  2. 在查询、更新、删除的时候,都是用find()方法创建对象。
    为了更好地理解save()方法,我们查看一下vendoryiisoftyyiwdbBaseActiveRecord.php代码。
 public function save($runValidation = true, $attributeNames = null)
    {
        if ($this->getIsNewRecord()) {
            return $this->insert($runValidation, $attributeNames);
        }

        return $this->update($runValidation, $attributeNames) !== false;
    }

当使用“new”关键字创建ActiveRecord 实例对象时则“$this->getIsNewRecord()”返回true,执行插入操作,否则执行更新操作。

随机小技巧

当表单提交操作时,如出现“Unable to verfy your data submission”错误,是被Yii2框架的CSRF验证拦截了。我们可以在控制器中把成员属性"public $enableCsrfValidation = false;"禁用。

ActiveQuery成员属性简介
属性类别描述
aliasstring表别名
distinctboolean是否只选赞不相同的数据行
groupBystring如何进行分组查询结果
havingstring作为GROUP-BY子句的条件
indexBystring作为查询结果数组的索引
joinstring如何加入其他的表
limitinteger要返回最多记录数
offsetinteger要返回从0开始的偏移量
orderBystring如何对结果进行排序
paranmsarray以参数占位符为索引的查询参数列表
selectmixed被选中的列
withmixed相关联的查询标准

列举一段代码来说明:

<?php
namespace app\controllers;

use app\models\Article;
use yii\db\ActiveQuery;
use yii\web\Controller;

class ArticleController extends Controller
{
    public function actionQuery()
    {
        $rows = new ActiveQuery(Article::tableName());
        $rows->select = ['id', 'title'];
        $rows->where = 'cid=:cid';
        $rows->params = [':cid' => 1];
        $article = $rows->one();
        return $this->render('article', ['list' => $article]);
    }
}

在实际应用查询构建类
构建查询语句时,更多的使用ActiveQuery类的成员方法。

ActiveQuery成员方法简介
方法名返回值类型描述
select()yii\db\Query指定SQL语句当中的SELECT子句
from()yii\db\Query指定SQL语句当中的FROM子句
where()yii\db\Query指定SQL语句当中的WHERE子句
groupBy()yii\db\Query指定SQL语句当中的GROUPBY子句
having()yii\db\Query指定SQL语句当中的HAVING子句
join()yii\db\Query指定SQL语句当中的JOIN子句
limit()yii\db\Query指定SQL语句当中的LIMIT子句
offset()yii\db\Query指定SQL语句当中的OFFSET子句
orderBy()yii\db\Query指定SQL语句当中的ORDERBY子句
union()yii\db\Query指定SQL语句当中的UNION子句
ActiveQuery常用返回结果集的成员方法
方法名返回值类型描述
all()array执行查询语句,并且以数组形式返回所有查询结果集
one()yii\db\ActiveRecord array null执行程序语句,返回一条程序结果集
column()array执行查询语句,返回结果集的第一列
scalar()string null false返回结果集的第一行第一列的标量值
exists()boolean判断结果集是存在
count()integer string返回SQL语句COUNT查询的结果
Query 类的where()成员方法简介 “where()”方法用法比较复杂,我们详细去说明一下。

where()成员方法属于yii\db\ActiveQuery的父类yii\db\Query。

成员方法where(),public Query where($condition, $params = [])

$conditionstring array yii\db\Expression用来指定SQL语句当中的WJHERE子句
$paramsyii\db\Query当前Query实例对象
{return}yii\db\Query当前Query实例对象

下面介绍常用的写法:

  • 在定义非常简单的查询条件的时候,字符串格式是最适合的。
//查询栏目ID为7的文章表的记录
$news = Article::find()
        ->where('cid=7')
        ->one();
  • 数组格式最适合指定多个“and”串联。
//SELECT * FROM `ds_article` WHERE (`cid`=6) AND (`title`='家用电器')
$news = Article::find()
                ->where(['cid' => 6, 'title' => '家用电器'])
                ->one();
  • 操作符格式允许指定类程序风格的任意条件语句

    • and: 操作数会被“and”关键字串联起来。
例如['and','id=1','id'=2']将会生成id=1 AND id = 1, 如果操作是一个数组,它也会转化字符串。例如,['and', 'type=1',['or','id=1','id=2']]将会生成type=1 AND (id=1 OR id=2)
  • between: 第一个操作数为字段名称,第二格和第三个操作数代表的是这个字段的取值范围。
例如: ['between','id',1,10]将会生成id BETWEEN 1 AND 10
  • in: 第一操作数为字段名称或者数据库表达式。第二个操作数既可以是一个数组,也可以是一个Query对象。如第二个操作数是一个数组,那么它代表的是取值范围。如果第二个操作数是Query对象,那么这个子查询的结果将会作为取值范围。
例如:['in','id',[1,2,3]] 将生成id IN(1,2,3)
  • like: 第一个操作数应为一个字段名或数据库表达式,第二个操作数可以是字符串或数组,代表第一个操作数需要模糊查询的值。
例如: ['like','name','tester']会生成 name LIKE "%tester%"
       如果单位制是一个数组,那么将会生成应“and” 串连起来的多个“like”语句。
例如: ['like','name',['test','sample']] 将会生成name LIKE "%test%" AND name LIKE "%smple%"
  • or like: 用法和like 操作符类似,区别在于当第二个操作数为数组时,会使用OR 来串联多个“like” 条件语句。
  • not like: 用法和“like” 操作符类似,区别在于会使用“NOT LIKE”来生成条件语句。
  • or not like: 用法和“not like” 操作符类似,区别在于会使用OR 来串联多个“not like” 条件语句。
  • exists:该操作数必须是代表子查询yii\db\Query的一个实例,会构建一个EXISTS表达式。
  • not exists:该操作数必须是代表子查询yii\db\Query的一个实例,会构建一个NOT EXISTS表达式。
  • >或 <=:第一个操作数必须为字段的名称,第二个操作数则应该为一个值。
   例如: ['>','age',10] 将会生成 age > 10

关联查询

场景:order表中的主键id 对应 order_log表中的 order_id,现在查询order表关联order_log中id=121的数据。
hasMany() 一对多 、 hasOne() 一对一

<?php

namespace app\models;

use yii\db\ActiveRecord;

class Order extends ActiveRecord
{
    public static function tableName()
    {
        return "{{order}}";
    }
    public function getOrderLog()
    {
//        return  self::find()->leftJoin('order_log','order_log.order_id=order.id')->asArray()->all();
        return $this->hasMany(OrderLog::className(),['order_id' => 'id']);
    }

    public function getList()
    {
        return self::find()->where('id = 121')->with('orderLog')->asArray()->all();
    }
}
控制器中调用: 
echo "<pre>";
print_r((new Order())->list);
Array
(
    [0] => Array
        (
            [id] => 121
            [is_del] => 0
            [send_time] => 1555904215
            [is_cancel] => 0
            [is_send] => 1
            [is_token] => 1
            [token_time] => 1566358763
            [orderLog] => Array
                (
                    [0] => Array
                        (
                            [id] => 1
                            [order_id] => 121
                            [log_msg] => 系统自动收货
                            [log_ip] => 127.0.0.1
                            [log_role] => 系统
                            [log_user] => 服务器
                            [log_order_state] => 0
                            [log_time] => 1566358763
                        )

                )

        )

)

关注友儿不迷路

Last modification:October 18th, 2019 at 03:56 pm
如果觉得我的文章对你有用,请随意赞赏