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

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个?

跨平台系列 cross-plateform 跨平台应用程序-01-概览 cross-plateform 跨平台应用程序-02-有哪些主流技术栈? cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个? cross-plateform 跨平台应用程序-04-React Native 介绍 cross-plateform 跨平台应用程序-05-Flutte