我们知道在 Yii 框架中,单表我们可以通过 findOne 方法查询,然后赋新值,最后执行 save 操作就可以更新数据了。像下面这样,我们将 Table 表中“id=1”的数据中的“name”更新成了“chengcheng2”。
$tmp = Table::findOne(['id' => 1]); $tmp->name = 'chengcheng2'; $tmp->save();
但是如果是两张表联查,并且需要更新两张表中的数据,那么该如何实现?像下面这样,数据来自 xh 表和 cp 表,然后需要更新的数据也是这两张表中的字段。
$info = Xh::find()->alias('xh') ->select(['cp.bh','cp.lb','xh.xh']) ->join('LEFT JOIN', 'cp', 'cp.cpbh = xh.cpbh') ->andWhere(['xh.xh' => $xh]) ->asArray()->one(); $info->bh = $bh; $info->lb = $lb; $info->xh = $xh; $info->save();
运行结果会报错,通过打印出 $info 你会发现,$info 是个数组结果;再打印上面的 $tmp 是个结果对象。
报错结果:
$tmp 对象:
object(app\models\v1\yidian\Cpxh)#102 (8) { ["_attributes":"yii\db\BaseActiveRecord":private]=> array(24) { ["id"]=> int(1) ... ... } ["_oldAttributes":"yii\db\BaseActiveRecord":private]=> array(24) { ["id"]=> int(1) ... ... } ["_related":"yii\db\BaseActiveRecord":private]=> array(0) { } ["_errors":"yii\base\Model":private]=> NULL ["_validators":"yii\base\Model":private]=> NULL ["_scenario":"yii\base\Model":private]=> string(7) "default" ["_events":"yii\base\Component":private]=> array(0) { } ["_behaviors":"yii\base\Component":private]=> array(0) { } }
解决方法:
首先在,xh表 models 里添加下面这个方法
public function getCp() { /** * 第一个参数为要关联的字表模型类名称, *第二个参数指定 通过子表的 cpbh(1) 去关联主表的 cpbh(2) 字段 */ return $this->hasOne(Cp::className(), ['bh' => 'bh']); }
然后在控制器里使用
//新方法实现 $info = xh::find() ->joinWith('cp') ->andWhere(['xh.bh' => $bh]) ->one(); $info->cp->bh = $bh; $info->cp->lb = $lb; $info->xh = $xh; $info->cp->save(); $info->save();
这样就已经使用了 Yii 框架的方法进行了多表的更新操作,无需写原生 SQL,防止了被注入的危险。