讲解一下ThinkPHP的关联模型

【详细分析】thinkphp反序列化漏洞 阅读详情

导读:thinkphp关联模型的,我一开始学习的的时候觉得对于一个逻辑业务简单,不太复杂的项目真没必要的去弄什么关联模型的。本质我想说我们再学php的时候不要的为了MVC而MVC,其次通过页面trace可以看出生成的sql语句效率不是太高的。但是如果你做一个cms或者比较复杂的系统的,系统本身表的结构就是很复杂的话,那么使用关联模型可以是整个业务逻辑变得有紧有条的,在这种的情况下我是比较推荐的。

   首先我要讲的是官方对关联的模型的解释和介绍:

   关联关系

通常我们所说的关联关系包括下面三种:
   一对一关联 :ONE_TO_ONE,包括HAS_ONE和BELONGS_TO

   一对多关联 :ONE_TO_MANY,包括HAS_MANY和BELONGS_TO

   多对多关联 :MANY_TO_MANY
   关联关系必然有一个参照表,例如:

       有一个员工档案管理系统项目,这个项目要包括下面的一些数据表:基本信息表、员工档案表、部门表、项目组表、银行卡表(用来记录员工的银行卡资料)。
       这些数据表之间存在一定的关联关系,我们以员工基本信息表为参照来分析和其他表之间的关联:
           每个员工必然有对应的员工档案资料,所以属于HAS_ONE关联;
           每个员工必须属于某个部门,所以属于BELONGS_TO关联;
           每个员工可以有多个银行卡,但是每张银行卡只可能属于一个员工,因此属于HAS_MANY关联;
           每个员工可以同时在多个项目组,每个项目组同时有多个员工,因此属于MANY_TO_MANY关联;


   分析清楚数据表之前的关联关系后,我们才可以进行关联定义和关联操作。

   。。。。。。。剩下都是通过手册可以看到的。。。。。。。。。


       好了 不都说什么的了。我讲解的是很简单的例子,假设我有两张表。一张是学生信息表tp_stus,一张是学生对应的班级表tp_classes。两张表各有一个主键,sid和cid,结构如下图:

   1.表tp_stus:

2.表tp_classes

在IndexAction中写入如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

// 本类由系统自动生成,仅供测试用途

classIndexAction extendsAction {

publicfunctionindex(){

if(!empty($_POST['up'])){

$Stus=D('Stus');

$Stus->create();

$Stus=$Stus->add();

}

//$Stus=D('Stus');

if(!empty($_POST['search'])){

$Stus=D('Stus');

$arr=$Stus->relation('class')->select();

}

//dump($arr);

$this->assign('arr',$arr);

$this->display();

}

}


在StusModel中写入如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

classStusModel extendsRelationModel{

protected$_auto=array(

array('time','time',3,'function'), // 对create_time字段在更新的时候写入当前时间戳

);

protected$_link=array(

'Classes'=>array(

'mapping_type'=>BELONGS_TO,

//'class_name'=>'Classes',

//外键,也就是表Stus中的字段

'foreign_key'=>'cid',

'mapping_name'=>'class',

//关联的字段,可以多个

'mapping_fields'=>'cname',

'as_fields'=>'cname:classname'

),

);

}



模版index.html就会显示如下的结构:

生成的sql语句如下:

       tips:数据量小的话是感觉和'select * from tp_stus,tp_classes where tp_stus.cid=tp_classes.cid,等效的语句没区别。也就是说关联模型最后的生成的sql语句其实是一个连接查询。数据关联处理复杂的时候就明显体现优势了,方便很多。告诉大家一下不同关联类型生成语句也是不同的呢

   大家可以看一下ThinkPHP关联模型的RelationModel.class.php源码是怎么处理生成sql语句的?

   RelationModel.class.php第130 line 的源码显示:

1

2

3

4

5

$mappingType= !empty($val['mapping_type'])?$val['mapping_type']:$val;//关联类型

$mappingClass= !empty($val['class_name'])?$val['class_name']:$key;// 关联类名

$mappingFields= !empty($val['mapping_fields'])?$val['mapping_fields']:'*';// 映射字段

$mappingCondition= !empty($val['condition'])?$val['condition']:'1=1';// 关联条件

$mappingKey=!empty($val['mapping_key'])? $val['mapping_key'] : $this->getPk(); // 关联键名


   后面的就是开始处理不同关联类型的model语句了,源码这样处理的我已经注释好了:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

// 获取关联模型对象

$model= D($mappingClass);

switch($mappingType) {

caseHAS_ONE://一对一

//关联类型构造model查询语句

$pk=  $result[$mappingKey];

$mappingCondition.= " AND {$mappingFk}='{$pk}'";

$relationData=$model->where($mappingCondition)->field($mappingFields)->find();

if(!empty($val['relation_deep'])){

$model->getRelation($relationData,$val['relation_deep']);

}                    

break;

caseBELONGS_TO://一对多

if(strtoupper($mappingClass)==strtoupper($this->name)) {

// 自引用关联 获取父键名

$mappingFk=!empty($val['parent_key'])? $val['parent_key'] : 'parent_id';

}else{

$mappingFk=   !empty($val['foreign_key'])?$val['foreign_key']:strtolower($model->getModelName()).'_id';     //  关联外键

}

$fk=  $result[$mappingFk];

$mappingCondition.= " AND {$model->getPk()}='{$fk}'";

//关联类型构造model查询语句

$relationData=  $model->where($mappingCondition)->field($mappingFields)->find();

if(!empty($val['relation_deep'])){

$model->getRelation($relationData,$val['relation_deep']);

}                    

break;

caseHAS_MANY://一对多

$pk=  $result[$mappingKey];

$mappingCondition.= " AND {$mappingFk}='{$pk}'";

$mappingOrder=  !empty($val['mapping_order'])?$val['mapping_order']:'';

$mappingLimit=  !empty($val['mapping_limit'])?$val['mapping_limit']:'';

// 延时获取关联记录  注意这边开始生成HAS_MANY关联类型构造model查询语句

$relationData=  $model->where($mappingCondition)->field($mappingFields)->order($mappingOrder)->limit($mappingLimit)->select();

if(!empty($val['relation_deep'])){

foreach($relationDataas$key=>$data){                        

$model->getRelation($data,$val['relation_deep']);

$relationData[$key]     =   $data;

}                          

}

break;

caseMANY_TO_MANY://多对多

$pk=  $result[$mappingKey];

$mappingCondition= " {$mappingFk}='{$pk}'";

$mappingOrder=  $val['mapping_order'];

$mappingLimit=  $val['mapping_limit'];

$mappingRelationFk= $val['relation_foreign_key']?$val['relation_foreign_key']:$model->getModelName().'_id';

$mappingRelationTable=  $val['relation_table']?$val['relation_table']:$this->getRelationTableName($model);

//关联类型构造model查询语句

$sql= "SELECT b.{$mappingFields} FROM {$mappingRelationTable} AS a, ".$model->getTableName()." AS b WHERE a.{$mappingRelationFk} = b.{$model->getPk()} AND a.{$mappingCondition}";

if(!empty($val['condition'])) {

$sql.= ' AND '.$val['condition'];

}

if(!empty($mappingOrder)) {

$sql.= ' ORDER BY '.$mappingOrder;

}

if(!empty($mappingLimit)) {

$sql.= ' LIMIT '.$mappingLimit;

}

$relationData=   $this->query($sql);

if(!empty($val['relation_deep'])){

foreach($relationDataas$key=>$data){                        

$model->getRelation($data,$val['relation_deep']);

$relationData[$key]     =   $data;

}                          

}                    

break;

}


   大家看了源码可能还不是很一下子理解,下面总结一下,便于对比理解:

   强调一下Thinkphp中表关联HAS_ONE和BELONGS_TO的区别:

   HAS_ONE

       例子:
       父关联对象表:
           cid
           cname
       子关联对象表:
           sid
           sname
           cid
   外键是:c_id

   BELONGS_TO:外键在你父联对象中
   父关联对象表:
       cid
       class_id
       product_name
   子关联对象表:
       class_id
       class_name
   外键是:
class_id

最后要说的也就是关联的相关操作了,无非就是增删改查一些操作。这一些都是建立在你定义关联基础上操作和之前crud没啥区别的

thinkphp5在Model模型里使用hasOne和belongto关联表查询 默认情况下,Thinkphp5.0使用的是user_id作为外键关联,如果不是的话则需要在关联定义的时候指定,例如:user表对应的的Model模型:Userphp//1.hasOne 一对一//2.hasMany 一对多//hasOne('关联模型名','外键名','主键名',['模型别名定义'],'join类型');?user_login表对应的Model模型:UserLoginphp。 阅读详情

相关推荐

Java 大视界 -- Java+Spark MLlib 构建智能推荐系统:协同过滤算法实战与优化(441)

Java+Spark MLlib构建智能推荐系统实战 本文详细介绍了基于Java和Spark MLlib构建协同过滤推荐系统的全流程实践方案。主要内容包括: 架构设计:采用离线批处理为主、近实时更新为辅的架构,包含数据采集层、处理层、模型层、推荐生成层、存储层和应用层六大模块,可支撑千万级用户推荐需求。 技术实现: 使用Spark MLlib的ALS算法进行协同过滤模型训练 提供数据清洗、模型训练、推荐生成等核心代码实现 采用MySQL存储推荐结果,支持批量插入和事务保障 生产级优化: 版本化模型存储规避覆

【青云交】华为云云享专家 | 阿里云开发者社区专家博主 技术圈个人影响力前 9 | 博客之星 TOP12 优快云 首位四榜(原力榜 / 作者周榜 / 领军人物 / 综合热榜)榜首,破平台纪录! 苏州地区全榜霸榜,感恩全网十多万粉丝同行! 2539

thinkphp关联模型详细说明

在复杂的关联操作中,如果要给关联定义增加可选的属性,我们可以采用完整定义的方式。 完整定义的格式是: protected $_link = array(     '关联表名1'  =>  array(         '该表的关联方式的属性1' => '定义',         '该表的关联方式的属性N' => '定义',     ),     '关联表名2'  =>  array(

xuchen_si的专栏 2744

Apifox CLI + Claude Skills:将接口自动化测试融入ai

基于 Apifox CLI、Claude Code以及Claude Skills组合,实现自然语言触发接口自动化测试。

wwz_0012的博客 598

[ POP链 ] thinkphp5.1.x~5.2.x

thinkphp 5.1.x~5.2.x反序列化思路学习 起点:/thinkphp/library/think/process/pipes/Windows.php的__destruct() __destruct()里面调用了两个函数,一个关闭连接close()方法,忽略,然后我们跟进removeFiles()函数。 这里使用了$this->files,而且这里的$files是可控的。所以存在一个任意文件删除的漏洞。 POC可以这样构造: namespace think\process\pipes;

Dannie01的博客 617

c764-基于Vue的实时温湿度监控系统

🌟 毕业设计指导交流 🌟 同学们好!作为一名计算机专业的技术爱好者,我在毕业设计领域积累了一些经验,希望能和大家分享交流。从选题到答辩,欢迎一起探讨技术问题。💡 技术方向: 熟悉Java全栈(SSM/Spring Boot)、Python数据分析、微信小程序/安卓开发等技术栈,可以互相学习项目开发经验。📂 学习资源: 整理了一些开源项目案例(含代码和文档),需要参考的同学可以留言讨论,也欢迎分享你的项目经验。🛠 交流内容:✨ 欢迎在评论区留言讨论,一起进步!记得遵守社区规范,保持学术

weixin_39513710的博客 1070

别再为GEE注册发愁了!用谷歌Cloud Project,5分钟搞定谷歌地球引擎账户(保姆级图文)

本文提供2024最新版谷歌地球引擎(GEE)账户注册的保姆级教程,通过谷歌Cloud Project快速完成注册,5分钟极速通关。详细解析注册前的准备、分步图解流程、常见误区及解决方案,帮助用户避开90%的注册陷阱,直达GEE核心功能区。

weixin_42557830的博客 200

Thinkphp 关联查询 详解 简单而方便的理解关联查询

关联查询本人使用的是thinkphp3.2.3版本 由于性能问题,新版取消了自动关联查询机制,而统一使用relation方法进行关联操作,relation方法不但可以启用关联还可以控制局部关联操作,实现了关联操作一切尽在掌握之中。 所以今天讲的主要是relation函数的具体使用方法 由于一对多模型比较适合讲解,所以在这里我将用一对多模型来为大家讲解一下relation函数的具体使用方法。 给

qq_36431213的博客 3308

【同花顺公式编辑教程】第3章 获取数据

学习同花顺公式编辑器,其提供的数据有量价数据以及财务数据。在本章中,我们讲解了编辑器执行代码的原理,并给出了可调用数据的汇总表。

LiaoYi2016218的博客 1万+

ThinkPHP对于数据库的关联操作+实例(完美收藏)

thinkphp 数据库

AKmumu的专栏 5335

C#函数返回多个值实现实例

本文实例讲解C#函数返回多个值多种实现方法。

qq_30725967的博客 1170

基于STM32单片机设计的智能水温控制系统

本项目研究并实现了一种基于STM32单片机的智能水温控制系统。系统以STM32F103RCT6作为主控制器,通过DS18B20温度传感器实时采集水温数据,利用PID控制算法精确调节5V直流防水型70W加热棒的功率输出,确保水温恒定在设定范围内。此外,采用OLED显示屏显示当前水温和预设上限阀值,并集成ESP8266-WiFi模块与自研Android手机APP进行远程通信和控制。用户可通过本地按键或手机APP设置温度阀值,实现实时监控与智能化管理。整个系统设计旨在提高水资源利用效率,提升生活及工业用水环境的舒

8790

think php5关联模型,实例讲解ThinkPHP5中关联模型2019-07-22

一、关联模型在关系型数据库中,表之间有一对一、一对多、多对多的关系。在 TP5 中,实现了ORM (Object Relational Mapping) 的思想,通过在模型中建立模型间的关联,实现建立表与表之间的关联。二、文章中用到的表结构所用的数据表和数据传到了百度云image 表,存储图片的位置信息banner 推荐位表,存储推荐位的类型banner_item 表,推荐位中的信息条目,可以看到...

weixin_29611239的博客 632

Access查询中的Dlookup函数的妙用

在Microsoft Access中,处理和分析数据的过程中,常常会遇到需要根据条件从其他记录中提取特定数据的情况。这时候,Dlookup函数就成了开发者和数据分析师的得力助手。今天我们将通过一个具体的实例,详细探讨如何利用Dlookup函数来解决复杂的查询问题。

m0_62153576的博客 295

关于thinkphp中关联模型的简单使用

thinkphp关联模型

dnidong的博客 3006

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Thinkphp5关联模型多对多的定义与使用

想了想我还是觉得在写一篇关于多对多的文档吧,因为我看了官方的文档写的不够细,不好理解。我自己也花了时间去看人家的文档还有自己又做了一些测试才知道怎么用的现在把我做测试的所有过程分享给大家。数据库表与数据       就从数据库表开始啦,因为这样可能会更利于大家去理解。大家都知道数据库多对多关系都是需要三张表来完成的,一张主表,一张关联表,还有一张中间表。比如我们这里主表是学生表关联课程表。因为一个学

u012600104的博客 1万+

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Thinkphp6知识点八——模型关联(一对一关联&相对关联)反向关联

附表关联主表称为反向关联,又称为相对关联 语法:belongsTo('关联模型(表)','当前模型外键', '关联模型主键');例如:ariticle模型里面belongsTo(Category::class, 'category_id', 'id') <?php namespace app\model; use think\Model; class article extends Model { public function category() { ...

程序世界 1708

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Thinkphp关联模型BELONGS_TO

通过一个栗子,简洁明了得让大家 BELONGS_TO 的用法~

若水弹丸之地 4803

ThinkPHP5模型中的一对一关联

定义一对一关联,例如,一个用户都有一个个人资料 其实程序中的表并非一开始并非是直接动手通过Navicat或者什么工具建表出来的,而是通过ER图,通过图形反应某张表与某张表之间的关系来的再建立相应的表,通过外键关联而来。 首先新建一张表为user,如图所示: 填入内容: 在建立一张表为info 填入内容: 这里我们需要知道,在设定之处我们认为,每一个用户只能够拥有一个个人信息,所以user对...

hgb24660的博客 537

thinkphp5中的模型关联

这次讲一下我对thinkphp中的模型理解,例子比较简单,如有错误请指正。 有这么两张表:新闻分类表 和 新闻表。 在设计表的时候,新闻表中cate_id 字段去关联分类 那么在查询的时候,

qq_41484622的博客 624

Thinkphp6知识点七——模型关联(一对一关联)

模型关联:关联模型就是将表与表之间进行关联和对象化,更高效的操作数据。 一对一关联:用户表与用户资料表关联,一个用户关联一条用户资料数据。 语法:hasOne('关联模型(表)',当前模型外键(关联表的相联系的外键),当前模型主键) <?php namespace app\model; use think\Model; class User extends Model { public function profile() { // hasOne('关.

程序世界 2782

tp5 模型关联

一、关联模型 在关系型数据库中,表之间有一对一、一对多、多对多的关系。在 TP5 中,实现了ORM (Object Relational Mapping) 的思想,通过在模型中建立模型间的关联,实现建立表与表之间的关联。 二、文章中用到的表结构 所用的数据表和数据传到了百度云 链接:http://pan.baidu.com/s/1hrXwEJa 密码:9r98 image 表,存储图片的...

qq_33481269的博客 522

TP5中关联模型

一、关联模型 在关系型数据库中,表之间有一对一、一对多、多对多的关系。在 TP5 中,实现了ORM (Object Relational Mapping) 的思想,通过在模型中建立模型间的关联,实现建立表与表之间的关联。 二、文章中用到的表结构 image 表,存储图片的位置信息 banner 推荐位表,存储推荐位的类型 banner_item 表,推荐位中的信息条目,可以看到它拥有外键 img_...

weixin_43772950的博客 1056

实例讲解TP5中关联模型

https://blog.youkuaiyun.com/github_37512301/article/details/75675054 一、关联模型在关系型数据库中,表之间有一对一、一对多、多对多的关系。在 TP5 中,实现了ORM (Object Relational Mapping) 的思想,通过在模型中建立模型间的关联,实现建立表与表之间的关联。 二、文章中用到的表结构 所用的数据表和数据传到了百度云...

weixin_33851604的博客 446

ThinkPHP的关联操作实例

用thinkphp这么久了,这个功能还一直没用过。 平时都是直接继承的Model类 我们以用户表为核心,来描述如何使用表的关联操作。假设存在如下的关联情况:每个用户有一个档案表是HAS_ONE关联;每个用户属于一个部门是BELONGS_TO关联;每个用户有多张银行卡是HAS_MANY关联;每个用户可能属于多个项目组,每个项目组也有多个用户是MANY_TO_MANY关联。我们首先来创建...

anche8334的博客 145
上一篇: PHP开发之53个要点提高PHP编程效率
下一篇: PHP正则替换函数preg_replace和preg_replace_callback使用总结
Lankecms
博客等级 码龄15年 14粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值