Yii框架relations的使用

2024-09-08 14:48
文章标签 使用 框架 yii relations

本文主要是介绍Yii框架relations的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

通过在 relations() 中声明这些相关对象,我们就可以利用强大的 Relational ActiveRecord (RAR) 功能来访问资讯的相关对象,例如它的作者和评论。不需要自己写复杂的 SQL JOIN 语句。
前提条件
在组织数据库时,需要使用主键与外键约束才能使用ActiveReocrd的关系操作;
场景
申明关系
两张表之间的关系无非三种:一对多;一对一;多对多; 在AR中,定义了四种关系:

关系                              定义  
BELONGS_TO              A和B的关系是一对多,那么B属于A   
HAS_MANY                A和B之间的关系是一对多,那么A有多个B
HAS_ONE                 这是HAS_MANY的一种特殊情况,A至多有一个B   
MANY_MANY               这个对应多对多的情况,在AR里会将多对多以BELONGS_TO和HAS_MANY的组合来解释

在AR中通过重写CActiveRecord类的relations()方法来申明关系;这个方法返回一个关系配置的数组;一个数组无素代表一个单独的关系,格式如下:
‘VarName’=>array(‘RelationType’,’ClassName’,’ForeignKey’, …additional options)

Var Name                关系名
Relation Type           四种关系:self::BELONGS_TO, self::HAS_ONE, self::HAS_MANY, self::MANY_MANY
Class Name              代表当前AR类要关联的那个AR类名
Foreign Key             实现关系的外键, 有可能有多个,即列名

‘select’: string|array, 被选中的列列表。默认值为 ‘*’,这意味着是所有列。 如果它们出现在一个表达式中(例如: COUNT(relationName.name) AS name_count)。
‘condition’: string, WHERE子句。 默认值为空。 注意,列引用需要加入’relationName’前缀 。(例如:relationName.age>20)
‘order’: string, ORDER BY子句。 默认值为空。 注意,列引用需要加入’relationName’前缀 。(例如:relationName.age DESC)
‘with’: string|array, 应该与这个对象一起装载的子对象相关名单。 注意,这仅仅是延迟加载,而不是预先加载。
‘joinType’: 联接类型。 默认值为‘LEFT OUTER JOIN’。
‘alias’: 关系与关联表的别名。 它默认为null, 意味着表的别名与关系名称相同。
‘params’: 参数绑定到要生成的SQL语句上。 这应作为名称-值的数组。
‘on’: ON 子句。 此处指定的条件将追加到使用 AND 运算符的联接条件。
‘index’: 其值应作为存储相关的对象的数组的键的列的名称。 此选项仅适用于, HAS_MANY 和 MANY_MANY 关系。
‘scopes’: 应用范围。在单一的范围情况下可以像’scopes’=>’scopeName’, 在多个作用域范围情况下可以使用数组像这样’scopes’=>array(‘scopeName1’,’scopeName2’)。

延迟加载时有一定的关系,下列选项可用:
‘group’: string, GROUP BY子句。 默认值为空。 注意,列引用需要加入’relationName’前缀 。(例如: relationName.age)。此选项仅适用于HAS_MANY 和 MANY_MANY 关系。
‘having’: string, HAVING子句。 默认值为空。 注意,列引用需要加入’relationName’前缀 。(例如: relationName.age)。此选项仅适用于HAS_MANY 和 MANY_MANY 关系。
‘limit’: 数据行的limit选择。 这个选项不能应用到BELONGS_TO。
‘offset’: 数据行的偏移量。 这个选项不能应用到BELONGS_TO。
‘through’: 获取相关的数据时将用作桥的模型的关系的名称。可以设置仅为 HAS_ONE 和 HAS_MANY。

return array(
'reply' => array(self::BELONGS_TO, 'BookPostReply', 'postid'),//连接BookPostReply表
);

self::BELONGS_TO默认是用当前指定的键跟关联表的主键进行join
默认生成的sql是 on id = postid,id是BookPostReply的主键。

需要生成 on BookPostReply.postid = t.postid,不去关联主键,而且关联其中一个字段的值

return array(
'reply' => array(self::BELONGS_TO, 'BookPostReply', '', 'on' => 't.postid=reply.postid'),
);

关联中的东西也可以有order的

'imgs'=>array(self::HAS_MANY,"LightProImgs","pid","order"=>"imgs.paixu desc","limit"=>3)

多表关联的实际应用:
1,首先多表关联是在models/xx.php的relations里配置的。而且是互配,但有区别。
格式:
‘VarName’=>array(‘RelationType’, ‘ClassName’, ‘ForeignKey’, …additional options)

需要弄清楚的几点:
1,VarName指什么? 详见下面例2。
2,RelationType。一共有4种,分别为self::HAS_MANY, self::BELONGS_TO, self::MANY_MANY, self::HAS_ONE。
3,ClassName。即关联的另一个../model/类名.php。
4,ForeignKey。谁是谁的外键?写了是用主键关联,为空两个表不是用主键关联需要on
5,附加条件

两个表不是用主键关联
‘user’ => array(self::BELONGS_TO, ‘OaskUser’, ” ,’on’=>’name=userName’ , ‘select’=>’TrueName’, ‘order’=>’sort asc’),

'varchar'=>array(self::HAS_ONE, 'CustomerEntityVarchar', 'entity_id','select'=>'varchar.value','on'=>'varchar.attribute_id="831"'),  

BELONGS_TO(属于): 如果表 A 和 B 之间的关系是一对多,则 表 B 属于 表 A ;
HAS_MANY(有多个): 如果表 A 和 B 之间的关系是一对多,则 A 有多个 B ;
HAS_ONE(有一个): 这是 HAS_MANY 的一个特例,A 最多有一个 B ;
MANY_MANY: 这个对应于数据库中的多对多关系。 由于多数 DBMS 不直接支持 多对多 关系,因此需要有一个关联表将多对多关系分割为一对多关系。在 AR术语中,我们可以解释 MANY_MANY 为 BELONGS_TO 和 HAS_MANY 的组合。
STAT :除了上述的关系类型,一个特殊的关系,称为STAT也支持 可用于进行统计查询(或聚合查询) 。 检索聚合对相关对象的信息,如数量。如 一篇日志共有多少个评论

'detailCounts' => array(self::STAT, 'PurchaseDetail', 'purchase_hid'),

例1,一对多关系 (post和user之间的关系)
(1)models/Post.php

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)'),);}
}

其中Post与User的关系是BELONGS_TO(多对一)关系,并通过Post的author_id与User关联。Post中author_id是外键,关联到User中。注:此处的VarName是author,一个对象 。
(2)models/User.php

class User extends CActiveRecord
{......public function relations(){return array('posts'=>array(self::HAS_MANY, 'Post', 'author_id'),);}
}

对于User,与Post的关系是属于HAS_MANY(一对多)关系。并通过Post的author_id与Post关联。 由于两者是一对多关系,所以要用posts

例2,多对多关系。中间表名( 本表外键, many表外键 )
在FailParts.php中

'Users' => array(self::MANY_MANY, 'User', 'fail_parts_user(fail_parts_id, user_id)'),

在User.php中

'FailParts' => array(self::MANY_MANY, 'FailParts', 'fail_parts_user(user_id, fail_parts_id)'),

由于两者是多对多关系,所以要用Users ,而不是User;要用FailParts,而不是FailPart。此处的Users和FailParts,即为前面的VarName。

例3,一对一关系。比较简单,暂略。

2,关于VarName。
对于类A.php,’VarName’=>array(‘RelationType’, ‘B’, ‘ForeignKey’, …additional options)
其中VarName与B基本相同。但未必完全一样。此时就可以在A的views/A/xx.php中通过VarName来访问B及其属性值了。
如果是一对一/一对多:A->VarName->name
如果是多对多:

$users = As->VarName
foreach($users as $u){$_tmp_users[] = $u -> getName;
}
userStr = implode(', ', $_tmp_users); 

懒惰式加载(lazy loading,也可译为 迟加载) 方式

// 获取 ID 为 10 的帖子
$post=Post::model()->findByPk(10);
// 获取帖子的作者(author): 此处将执行一个关联查询。
$author=$post->author;

懒惰式加载用起来很方便,但在某些情况下并不高效。
渴求式加载(eager loading)方式。$posts=Post::model()->with(‘author’,’categories’)->findAll();
AR scopes

//SchoolDepartment::model()->allDepartmentAndClass($id)->findAll();
public function relations() {return array('class' => array(self::HAS_MANY, 'SchoolClass', 'school_department_id'),);
}public function scopes() {return array('allDepartmentAndClass',);
}public function allDepartmentAndClass($id) {$this->getDbCriteria()->mergeWith(array('with' => "class",'condition' => "t.tbl_school_id=$id",));return $this;
}

强制查询使用join连接查询

 $criteria->together = true;

下面介绍是一种“急切导入”方法:在使用find和findAll时,使用with()方法,例:

$posts=Post::model()->with('author')->findAll()  
$posts=Post::model()->with('author')->findAll()

这样就可以在一次查询时连同查询其他信息了;with方法可以接受多个关系:

$posts=Post::model()->with('author','categories')->findAll();  
$posts=Post::model()->with('author','categories')->findAll();

这样就可以将作者和类别的信息一并进行查询;同样,with还支持多重急切导入

$posts=Post::model()->with( 'author.profile', 'author.posts', 'categories')->findAll();

http://blog.csdn.net/xinqingch/article/details/8219330
http://hudeyong926.iteye.com/blog/1274077

这篇关于Yii框架relations的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1148405

相关文章

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

如何使用Lombok进行spring 注入

《如何使用Lombok进行spring注入》本文介绍如何用Lombok简化Spring注入,推荐优先使用setter注入,通过注解自动生成getter/setter及构造器,减少冗余代码,提升开发效... Lombok为了开发环境简化代码,好处不用多说。spring 注入方式为2种,构造器注入和setter

MySQL中比较运算符的具体使用

《MySQL中比较运算符的具体使用》本文介绍了SQL中常用的符号类型和非符号类型运算符,符号类型运算符包括等于(=)、安全等于(=)、不等于(/!=)、大小比较(,=,,=)等,感兴趣的可以了解一下... 目录符号类型运算符1. 等于运算符=2. 安全等于运算符<=>3. 不等于运算符<>或!=4. 小于运

使用zip4j实现Java中的ZIP文件加密压缩的操作方法

《使用zip4j实现Java中的ZIP文件加密压缩的操作方法》本文介绍如何通过Maven集成zip4j1.3.2库创建带密码保护的ZIP文件,涵盖依赖配置、代码示例及加密原理,确保数据安全性,感兴趣的... 目录1. zip4j库介绍和版本1.1 zip4j库概述1.2 zip4j的版本演变1.3 zip4

Python 字典 (Dictionary)使用详解

《Python字典(Dictionary)使用详解》字典是python中最重要,最常用的数据结构之一,它提供了高效的键值对存储和查找能力,:本文主要介绍Python字典(Dictionary)... 目录字典1.基本特性2.创建字典3.访问元素4.修改字典5.删除元素6.字典遍历7.字典的高级特性默认字典

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

使用Python删除Excel中的行列和单元格示例详解

《使用Python删除Excel中的行列和单元格示例详解》在处理Excel数据时,删除不需要的行、列或单元格是一项常见且必要的操作,本文将使用Python脚本实现对Excel表格的高效自动化处理,感兴... 目录开发环境准备使用 python 删除 Excphpel 表格中的行删除特定行删除空白行删除含指定