Yii框架中ActiveRecord使用 Relations
2012-01-06 15:32
344 查看
前提条件
在组织数据库时,需要使用主键与外键约束才能使用ActiveReocrd的关系操作;
场景
下面的一个ER图显示的是一个例子
![](http://pswiki.baidu.com/twiki/pub/Main/Suzhouwei_Yii/relation_image.png)
ER图
在AR中通过重写CActiveRecord类的relations()方法来申明关系;这个方法返回一个关系配置的数组;一个数组无素代表一个单独的关系,格式如下:
'VarName'=>array('RelationType','ClassName','ForeignKey',...additional options)
下面的代码表示用来定义Post, User之间的关系
使用时,如果$author代表一个USER的AR实例,可以使用$author->posts来获取到它相关的所有的Post对象。
例:
如果没有关联的对象,那么将返回NULL或者一个空数组;BELONGS_TO和HAS_ONE结果为NULL,而HAS_MANY和MANY_MANY返回一个空数组。
上面的这种“懒惰导入”方法使用起来非常方便,但是在一些场景下不是非常的效率,比如,如果我们想访问N个POST的作者的信息,使用这种懒惰导入的方法将会执行N个join查询;
这样就可以在一次查询时连同查询其他信息了;with方法可以接受多个关系:
这样就可以将作者和类别的信息一并进行查询;同样,with还支持多重急切导入
上面的代码不仅会返回autho和categories信息,还会返回作者的profile和posts信息
这种“急切导入”方法也支持CDbCriteria::with,下面这两种实现方式效果一样:
select 定义从AR类中被select的列集合,如果定义为*,则表示查询所有列 condition 定义where语句,默认为空。 params 生成SQL语句的参数,这个需要用一个key-value对的数组来表示; on ON语句,这个条件用来通过AND添加一个joining condintion语句 order ORDER语句 with 和当前对象一起导出的相关对象列表,要注意如果使用不正确,有可能导致无限死循环; joinType 定义join的类别,默认为LEFT OUTER JOIN alias 定义别名,当多个表中有相同的columnname时,需要为表格定义alias,然后使用tablename.columnname来指定不同的column together 这个只在HAS_MANY,MANY_MANY时有用,在实现跨表查询时,可以用这个参数来控制性能。正常用不到,不详细讲述; join JOIN语句 group GROUP语句 having HAVING语句 index 这个值用来设定返回的结果数组以哪个column做为index值,如果不设定这个值的话,将从0开始组织结果数组。
除此之外还包含下面几个选项,在“懒惰导出”的特定关系时可用
limit 返回结果数量的限制,不适用于BELONG_TO关系 offset offset结果数量的值,不适用于BELONG_TO关系
下面代码,显示上面选项的一些使用:
此时,我们使用$author->posts时,会返回固定ORDER的POST信息
在组织数据库时,需要使用主键与外键约束才能使用ActiveReocrd的关系操作;
场景
下面的一个ER图显示的是一个例子
![](http://pswiki.baidu.com/twiki/pub/Main/Suzhouwei_Yii/relation_image.png)
ER图
申明关系
两张表之间的关系无非三种:一对多;一对一;多对多; 在AR中,定义了四种关系:BELONGS_TO | A和B的关系是一对多,那么B属于A | Post属于User |
HAS_MANY | A和B之间的关系是一对多,那么A有多个B | User有多个Post |
HAS_ONE | 这是HAS_MANY的一种特殊情况,A至多有一个B | User至多有一个Profile |
MANY_MANY | 这个对应多对多的情况,在AR里会将多对多以BELONGS_TO和HAS_MANY的组合来解释 | Post和Category |
'VarName'=>array('RelationType','ClassName','ForeignKey',...additional options)
VarName | 关系名 |
---|---|
RelationType | 四种关系:self::BELONGS_TO, self::HAS_ONE, self::HAS_MANY,self::MANY_MANY |
ClassName | 代表当前AR类要关联的那个AR类名 |
ForeignKey | 实现关系的外键, 有可能有多个,即列名 |
class Post extends CActiveRecord { ...... public function relations() { return array( 'author'=>array(self::BELONGS_TO, 'User', 'author_id'), 'categories'=>array(self::MANY_MANY, 'Category', 'tbl_post_category(post_id, category_id)'), ); } } class User extends CActiveRecord { ...... public function relations() { return array( 'posts'=>array(self::HAS_MANY, 'Post', 'author_id'), 'profile'=>array(self::HAS_ONE, 'Profile', 'owner_id'), ); } }
使用时,如果$author代表一个USER的AR实例,可以使用$author->posts来获取到它相关的所有的Post对象。
执行关系查询
懒惰导入查询方法
最简单的方法就是为AR对象添加一个关联属性,例:
// 获取PK为10的POST对象 $post=Post::model()->findByPk(10); // 获取这个POST的作者 $author=$post->author;
如果没有关联的对象,那么将返回NULL或者一个空数组;BELONGS_TO和HAS_ONE结果为NULL,而HAS_MANY和MANY_MANY返回一个空数组。
上面的这种“懒惰导入”方法使用起来非常方便,但是在一些场景下不是非常的效率,比如,如果我们想访问N个POST的作者的信息,使用这种懒惰导入的方法将会执行N个join查询;
急切导入查询方法
下面介绍是一种“急切导入”方法:在使用find和findAll时,使用with()方法,例:$posts=Post::model()->with('author')->findAll()
这样就可以在一次查询时连同查询其他信息了;with方法可以接受多个关系:
$posts=Post::model()->with('author','categories')->findAll();
这样就可以将作者和类别的信息一并进行查询;同样,with还支持多重急切导入
$posts=Post::model()->with( 'author.profile', 'author.posts', 'categories')->findAll();
上面的代码不仅会返回autho和categories信息,还会返回作者的profile和posts信息
这种“急切导入”方法也支持CDbCriteria::with,下面这两种实现方式效果一样:
$criteria=new CDbCriteria; $criteria->with=array( 'author.profile', 'author.posts', 'categories', ); $posts=Post::model()->findAll($criteria); or $posts=Post::model()->findAll(array( 'with'=>array( 'author.profile', 'author.posts', 'categories', ) );
关系查询选项
前面提过,在申明关系时可以添加额外的选项,这些选项都是一些key-value对,是用来定制关系查询的,总结如下:select 定义从AR类中被select的列集合,如果定义为*,则表示查询所有列 condition 定义where语句,默认为空。 params 生成SQL语句的参数,这个需要用一个key-value对的数组来表示; on ON语句,这个条件用来通过AND添加一个joining condintion语句 order ORDER语句 with 和当前对象一起导出的相关对象列表,要注意如果使用不正确,有可能导致无限死循环; joinType 定义join的类别,默认为LEFT OUTER JOIN alias 定义别名,当多个表中有相同的columnname时,需要为表格定义alias,然后使用tablename.columnname来指定不同的column together 这个只在HAS_MANY,MANY_MANY时有用,在实现跨表查询时,可以用这个参数来控制性能。正常用不到,不详细讲述; join JOIN语句 group GROUP语句 having HAVING语句 index 这个值用来设定返回的结果数组以哪个column做为index值,如果不设定这个值的话,将从0开始组织结果数组。
除此之外还包含下面几个选项,在“懒惰导出”的特定关系时可用
limit 返回结果数量的限制,不适用于BELONG_TO关系 offset offset结果数量的值,不适用于BELONG_TO关系
下面代码,显示上面选项的一些使用:
class User extends CActiveRecord { public function relations() { return array( 'posts'=>array(self::HAS_MANY, 'Post', 'author_id', 'order'=>'posts.create_time DESC', 'with'=>'categories'), 'profile'=>array(self::HAS_ONE, 'Profile', 'owner_id'), ); } }
此时,我们使用$author->posts时,会返回固定ORDER的POST信息
相关文章推荐
- Yii框架中ActiveRecord使用Relations
- Yii框架中ActiveRecord使用Relations
- Yii框架中ActiveRecord使用Relations
- [我的PHP之旅] YII框架学习 03.连接数据库(使用ActiveRecord)
- 解决yii框架中,使用参数化查询时,IN只能查询一个的代替方法
- Yii框架使用魔术方法实现跨文件调用功能示例
- yii2框架中使用下拉菜单的自动搜索yii-widget-select2实例分析
- YII使用relations关联聚合指定字段
- Yii框架中使用ChromePhp调试
- PHP的Yii框架使用中的一些错误解决方法与建议
- Yii框架官方指南系列24——使用数据库:Query Builder
- YII框架之soap协议的配置跟使用(Webservice)
- 详解PHP的Yii框架中自带的前端资源包的使用
- YII Framework框架教程之使用YIIC快速创建YII应用详解
- yii的relations方法的使用
- 详解PHP的Yii框架中扩展的安装与使用
- 在zend studio中使用yii框架
- 关于后盾网yii框架的学习小结(5)--验证码的使用与规则的设置,为后台模块设置独立的布局
- Yii框架中使用PHPExcel导出Excel文件
- 使用YII框架的migrate迁移数据库