yii添删改查实例(6)

总体来说,命名范围必须出现在一个 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 查询将被忽略。

三、Relational Active Record(关联查询)

我们已经知道如何通过Active Record(AR)从单个数据表中取得数据了,在这一节中,我们将要介绍如何使用AR来连接关联的数据表获取数据。

在使用关联AR之前,首先要在数据库中建立关联的数据表之间的主键-外键关联,AR需要通过分析数据库中的定义数据表关联的元信息,来决定如何连接数据。

1、如何声明关联

在使用AR进行关联查询之前,我们需要告诉AR各个AR类之间有怎样的关联。

AR类之间的关联直接反映着数据库中这个类所代表的数据表之间的关联。从关系数据库的角度来说,两个数据表A,B之间可能的关联有三种:一对多,一对一,多对多。而在AR中,关联有以下四种:

BELONGS_TO: 如果数据表A和B的关系是一对多,那我们就说B属于A(B belongs to A)。

HAS_MANY: 如果数据表A和B的关系是多对一,那我们就说B有多个A(B has many A)。

HAS_ONE: 这是‘HAS_MANY'关系中的一个特例,当A最多有一个的时候,我们说B有一个A (B has one A)。

MANY_MANY:

这个相当于关系数据库中的多对多关系。因为绝大多数关系数据库并不直接支持多对多的关系,这时通常都需要一个单独的关联表,把多对多的关系分解为两个一对

多的关系。用AR的方式去理解的话,我们可以认为 MANY_MANY关系是由BELONGS_TO和HAS_MANY组成的。

在AR中声明关联,是通过覆盖(Override)父类CActiveRecord中的relations()方法来实现的。这个方法返回一个包含了关系定义的数组,数组中的每一组键值代表一个关联:

'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options)

这里的VarName是这个关联的名称;RelationType指定了这个关联的类型,有四个常量代表了四种关联的类型:

self::BELONGS_TO,self::HAS_ONE,self::HAS_MANY和self::MANY_MANY;

ClassName是这个关系关联到的AR类的类名;ForeignKey指定了这个关联是通过哪个外键联系起来的。后面的additional

options可以加入一些额外的设置,后面会做介绍。

下面的代码演示了如何定义User和Post之间的关联。

class Post extends CActiveRecord { public function relations() { return array( 'author'=>array( self::BELONGS_TO, 'User', 'authorID' ), 'categories'=>array( self::MANY_MANY, 'Category', 'PostCategory(postID, categoryID)' ), ); } } class User extends CActiveRecord { public function relations() { return array( 'posts'=>array( self::HAS_MANY, 'Post', 'authorID' ), 'profile'=>array( self::HAS_ONE, 'Profile', 'ownerID' ), ); } }

说明: 有时外键可能由两个或更多字段组成,在这里可以将多个字段名由逗号或空格分隔,

一并写在这里。对于多对多的关系,关联表必须在外键中注明,例如在Post类的categories

关联中,外键就需要写成PostCategory(postID, categoryID)。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/bf9280780cbdcd28ce43da082ea5f146.html