Yii2中如何将createCommand查询结果转为模型而非关联数组
在Yii2中使用createCommand获取模型形式的结果
当你用createCommand执行查询时,默认返回的是关联数组或对象数组,要是想直接拿到对应的ActiveRecord模型实例,我在项目里常用这几种方法来实现:
方法一:手动映射数组到模型实例
这是最直观的方式,把查询返回的数组逐个赋值给模型:
// 执行查询,获取关联数组结果 $rows = Yii::$app->db->createCommand( 'SELECT * FROM user WHERE status = :status', [':status' => 1] )->queryAll(); // 转换为User模型数组 $userModels = []; foreach ($rows as $row) { $model = new \app\models\User(); // 第二个参数设为false,跳过属性验证(数据库查出来的数据无需验证) $model->setAttributes($row, false); $userModels[] = $model; }
如果是单条结果,直接处理单个模型即可:
$row = Yii::$app->db->createCommand( 'SELECT * FROM user WHERE id = :id', [':id' => 100] )->queryOne(); $userModel = new \app\models\User(); $userModel->setAttributes($row, false);
方法二:利用ActiveRecord的populate静态方法
Yii2的ActiveRecord自带了populate()静态方法,专门用来批量把查询数组转换成模型实例,代码更简洁:
// 先构造查询(也可以直接用原生SQL的createCommand) $query = (new \yii\db\Query()) ->select('*') ->from('user') ->where(['status' => 1]); // 创建命令并执行查询 $command = $query->createCommand(); $rows = $command->queryAll(); // 批量转换为模型 $userModels = \app\models\User::populate($rows);
这个方法内部其实也是循环赋值属性,但框架封装好了,用起来更省心。
额外提示:让模型支持直接更新
上面得到的模型默认isNewRecord属性为true,如果之后想直接调用save()更新数据,需要手动设置主键并标记为非新记录:
foreach ($userModels as $model) { // 假设你的主键是id $model->isNewRecord = false; // 更严谨的方式:$model->setOldAttribute('id', $model->id); }
这样之后,调用$model->save()就会执行UPDATE语句而不是INSERT语句了。
内容的提问来源于stack exchange,提问作者A. Ding
相关产品推荐
相关产品推荐

