lz19881123 2011-08-10 14:33:22 5580次浏览 0条回复 2 0 0

9、自定义 CActiveRecord 提供了几个占位符方法,它们可以在子类中被覆盖以自定义其工作流。 beforeValidate 和 afterValidate:这两个将在验证数据有效性之前和之后被调用。 beforeSave 和 afterSave: 这两个将在保存 AR 实例之前和之后被调用。 beforeDelete 和 afterDelete: 这两个将在一个 AR 实例被删除之前和之后被调用。 afterConstruct: 这个将在每个使用 new 操作符创建 AR 实例后被调用。 beforeFind: 这个将在一个 AR 查找器被用于执行查询(例如 find(), findAll())之前被调用。 afterFind: 这个将在每个 AR 实例作为一个查询结果创建时被调用。 10、使用AR处理事务 每个 AR 实例都含有一个属性名叫 dbConnection ,是一个 CDbConnection 的实例,这样我们可以在需要时配合 AR 使用由 Yii DAO 提供的 事务 功能:

$model=Post::model();
$transaction=$model->dbConnection->beginTransaction();
try
{
    // 查找和保存是可能由另一个请求干预的两个步骤
    // 这样我们使用一个事务以确保其一致性和完整性
    $post=$model->findByPk(10);
    $post->title='new post title';
    $post->save();
    $transaction->commit();
}
catch(Exception $e)
{
    $transaction->rollBack();
}

11、命名范围 命名范围(named scope)表示一个命名的(named)查询规则,它可以和其他命名范围联合使用并应用于Active Record查询。 命名范围主要是在 CActiveRecord::scopes() 方法中以名字-规则对的方式声明。如下代码在Post模型类中声明了两个命名范围, published 和 recently。

class Post extends CActiveRecord
{
    ......
    public function scopes()
    {
        return array(
            'published'=>array(
                'condition'=>'status=1',
            ),
            'recently'=>array(
                'order'=>'create_time DESC',
                'limit'=>5,
            ),
        );
    }
}

每个命名范围声明为一个可用于初始化 CDbCriteria 实例的数组。例如,recently 命名范围指定 order 属性为 create_time DESC , limit 属性为 5。他们翻译为查询规则后就会返回最近的5篇帖子。 命名范围多用作 find 方法调用的修改器。几个命名范围可以链到一起形成一个更有约束性的查询结果集。例如,要找到最近发布的帖子,我们可以使用如下代码:

$posts=Post::model()->published()->recently()->findAll();

总体来说,命名范围必须出现在一个 find 方法调用的左边。它们中的每一个都提供一个查询规则,并联合到其他规则,包括传递给 find 方法调用的那一个。最终结果就像给一个查询添加了一系列过滤器。 命名范围也可用于 update 和 delete 方法。例如,如下代码将删除所有最近发布的帖子: Post::model()->published()->recently()->delete(); 注意: 命名范围只能用于类级别方法。也就是说,此方法必须使用 ClassName::model() 调用。 12、参数化的命名范围 命名范围可以参数化。例如,我们想自定义 recently 命名范围中指定的帖子数量,要实现此目的,不是在CActiveRecord::scopes 方法中声明命名范围,而是需要定义一个名字和此命名范围的名字相同的方法:

public function recently($limit=5)
{
    $this->getDbCriteria()->mergeWith(array(
        'order'=>'create_time DESC',
        'limit'=>$limit,
    ));
    return $this;
}

然后,我们就可以使用如下语句获取3条最近发布的帖子。 $posts=Post::model()->published()->recently(3)->findAll(); 上面的代码中,如果我们没有提供参数 3,我们将默认获取 5 条最近发布的帖子。 13、默认的命名范围 模型类可以有一个默认命名范围,它将应用于所有 (包括相关的那些) 关于此模型的查询。例如,一个支持多种语言的网站可能只想显示当前用户所指定的语言的内容。因为可能会有很多关于此网站内容的查询,我们可以定义一个默认的命名范围以解决此问题。为实现此目的,我们覆盖 CActiveRecord::defaultScope 方法如下:

class Content extends CActiveRecord
{
    public function defaultScope()
    {
        return array(
            'condition'=>"language='".Yii::app()->language."'",
        );
    }
}

现在,如果下面的方法被调用,将会自动使用上面定义的查询规则:

$contents=Content::model()->findAll();

注意,默认的命名范围只会应用于 SELECT 查询。INSERT, UPDATE 和 DELETE 查询将被忽略

    没有找到数据。
您需要登录后才可以回复。登录 | 立即注册