数据库+模型 - AR查询器

  • 作者:KK

  • 发表日期:2016.12.23

  • 更新日期:2017.01.22


初步了解

AR模型查询的时候除了有模型::findOne(条件)模型::findAll(条件)以外,第三种常见的使用方式就是先通过find方法创建一个AR查询器(yii\db\ActiveQuery),代码就是这样的模型::find()->where($condition)...->all()

先试一下:

$testList = Test::find()->where(['type' => 3])->all();
foreach($testList as $test){
	echo $test->id;
}

这样find,where,all后返回的也是一个数组,而每个元素都是一个Test模型实例,实际上是跟Test::findAll(['type' => 3])是等效的


find方法的存在意义

写那么长,那不如写短一点?是啊,如果真是上面这样我也宁愿写短一点,但有时候还是要靠find方法

find方法其实不做任何实际的查询,它只是创建一个查询器,你可以理解成这样一个思想:

public static function find(){
	$query = new \yii\db\ActiveQuery();
	$query->from(static::tableName());
	return $query;
}

这里它返回的ActiveQuery也是一个查询器,跟yii\db\Query这个查询器是同一性质的东西

区别是:Query只查出纯数组形式的结果集,而ActiveQuery是查出对象形式的数据模型对象实例结果集,可谓是一个轻量级,一个重量级

其中ActiveQuery(好了我以后都简称为AR查询器了)也能像Query一样where() select() limit() orderBy one() all()....

但是不能from(),实际上AR查询器并没有from方法让我们去设定表名(所以其实我上面的代码是无效的!它只是一个思想演示),它是通过别的方法与一个模型的表进行绑定的,我就不说那么复杂了

好了既然返回一个查询器,就可以想像到我们可以自由地控制一些查询参数来实现更多丰富的查询,这就是find方法的存在意义,也就是AR查询器的存在意义,比如要查询最高分的前10名用户:

$users = User::find()
	->where(['sex' => 1])
	->orderBy(['score' => SORT_DESC])
	->limit(10)
	->all();

返回纯数组的结果

其实靠AR查询器也能像普通Query查询器一样查出纯数组结果,只要声明asArray就可以:

$users = User::find()
	->select(['id', 'name', 'sex']) //只要其中三个字段
	->where(['sex' => 1])
	->orderBy(['add_time' => SORT_DESC])
	->limit(10)
	->asArray() //以数组形式返回
	->all();

杂谈

Model::find()->where()->limit()...的时候,咱们可以这样来阅读理解find:模型 准备进行 查找|查询工作了,where条件...

但是不要老想着“模型要执行查询”,因为find的时候还没执行查询,只是创建查询器,所以只能说是准备进行查询了

从语义的角度出发的话,我甚至觉得它可以命名为buildQueryTest::buildQuery()->where(['type' => 3])->all()