我有一个系统,其中MySQL数据库中的所有表都填充了外部数据(每5分钟与另一个系统同步)。所有表都有一列DELFLAG
,用于标记已禁用的条目。
所以我在Yii中有大约15个与这些表相关联的AR模型。每当我进行查询时,我都需要添加类似$criteria->addCondition('DELFLAG=0')
的内容。如果查询中存在多个表,则会变得很难看,因为每个表都有标志。此外,如果我忘记了其中一个条件,就有可能出错。
以下是我现在的表现:
public function search($showtype = NULL) {
$criteria=new CDbCriteria;
if (isset($showtype)) {
$criteria->with = array(
'TSSSHOW',
'TSSSHOW.TSSSHOWTYPEITEM',
'TSSSHOW.TSSSHOWTYPEITEM.TSSSHOWTYPE'
);
$criteria->compare('TSSSHOWTYPEITEM.TSSSHOWTYPEID', $showtype);
$criteria->addCondition('TSSSHOW.DELFLAG=0');
$criteria->addCondition('TSSSHOWTYPEITEM.DELFLAG=0');
}
$exp = new CDbExpression("`TSSEVENT_START_DATETIME` > NOW()");
$criteria->addCondition($exp);
$criteria->addCondition('t.DELFLAG=0');
$criteria->together = true;
$criteria->order = 't.TSSEVENT_START_DATETIME ASC';
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'pagination' => array(
'pageSize' => 15,
),
));
}
是否有方便的方法将此条件包含在包含这些表的每个查询中?也许我的模型应该是一个特殊的类(而不是默认的CActiveRecord
)?
答案 0 :(得分:1)
我建议为这些模型声明命名范围:
public function scopes()
{
return array(
'disabledEntry'=>array(
'condition'=>'DELFLAG=1',
),
);
}
使用命名范围:Model::model()->disabledEntry()->findAll();
您还可以在with()语句中声明模型时提供范围:ModelA::model()->with('model:disabledEntry')->findAll();
但是如果你每次都必须设置这个条件,你可以设置defaultScope:
public function defaultScope()
{
return array(
'condition' => 'DELFLAG=0',
);
}
因此,默认情况下此模型具有此条件。
更新:由于您在多个模型中具有相同名称的列,因此在构建sql-query时,YII可能会出现一些列名歧义问题。如果是这种情况,请在范围声明中使用alias
或使用以下语句在声明范围'condition' => $this->getTableAlias(false, false) . '.DELFLAG=0',
时显式设置当前表别名
答案 1 :(得分:0)
您可以创建自己的类,例如CustomActiveRecord扩展了CActiveRecord 那你应该用你的标准覆盖findAll,findByPk方法..
其他解决方案是在每次导入后运行此查询'DELETE FROM table_name WHERE DELFLAG = 1'。