当前位置: 首页 > news >正文

ThinkPHP 一对多关联

用一对多关联的前提

多的一方的数据库表有一的一方数据库表的外键。

举例,用户获取自己的所有文章

数据表结构如下

// 用户表
useruser_id - integer  // 用户主键name - varchar // 用户名称// 文章表
articlearticle_id - integer // 文章主键title - varchar // 文章名标题content - text // 文章内容user_id - integer // 作者 user_id

多的一方(文章表)存在一的一方(用户表)的外键 user_id 。

一对多关联定义

用户表 user 模型:

<?phpnamespace app\api\model;class User extends Base
{// 不是默认主键名称记得定义 pk 属性protected $pk = 'user_id';// 获取用户详情以及用户的所有文章public static function getDetail(int $user_id){return self::get($user_id, 'articles');}// 一对多获取用户的文章public function articles(){// 完整写法return $this->hasMany('Article', 'user_id', 'user_id');}
}

hasMany 方法参数如下:

hasMany('关联模型', '关联模型外键', '当前模型主键');

除了关联模型外,其它参数都是可选。

  • 关联模型(必须):模型名或者模型类名
  • 关联模型外键:关联模型外键,默认的外键名规则是当前模型名+_id
  • 当前模型主键:当前模型主键,一般会自动获取也可以指定传入

实例演示

shop_article 表

 shop_user 表

演示1

获取 user_id 为 1 的用户详情以及用户的所有文章

用户 User 控制器

<?phpnamespace app\api\controller;use app\api\model\User as UserModel;class User extends Base
{public function detail(){$user_id = 1;$detail = UserModel::getDetail($user_id);echo '<pre>';var_dump($detail);echo '</pre>';}
}

用户表 User 模型

<?phpnamespace app\api\model;class User extends Base
{// 不是默认主键名称记得定义 pk 属性protected $pk = 'user_id';// 获取用户详情以及用户的所有文章public static function getDetail(int $user_id){return self::get($user_id, 'articles');}// 一对多获取用户的文章public function articles(){// 完整写法return $this->hasMany('Article', 'user_id', 'user_id');}
}

user 控制器  detail 方法输出

object(app\api\model\User)#41 (2) {["data"]=>array(4) {["user_id"]=>int(1)["name"]=>string(5) "admin"["create_time"]=>int(1688452509)["update_time"]=>int(1688452509)}["relation"]=>array(1) {["articles"]=>object(think\model\Collection)#50 (1) {["items":protected]=>array(2) {[0]=>object(app\api\model\Article)#45 (2) {["data"]=>array(6) {["article_id"]=>int(1)["title"]=>string(12) "测试标题"["content"]=>string(12) "测试内容"["user_id"]=>int(1)["create_time"]=>int(1689401566)["update_time"]=>int(1689401566)}["relation"]=>array(0) {}}[1]=>object(app\api\model\Article)#46 (2) {["data"]=>array(6) {["article_id"]=>int(2)["title"]=>string(13) "测试标题1"["content"]=>string(13) "测试内容1"["user_id"]=>int(1)["create_time"]=>int(1689498967)["update_time"]=>int(1689498967)}["relation"]=>array(0) {}}}}}
}

单条查询输出的是 User 模型实例,User 模型实例的 relation 属性(关联数组)保存着关联模型,在该关联数组中,关联方法名 articles 作为键名,关联查询结果作为键值(对一关联查询返回模型实例,对多关联查询返回结果集对象)。

使用的 SQL 如下

SELECT * FROM `shop_user` WHERE `user_id` = 1 LIMIT 1SELECT * FROM `shop_article` WHERE `user_id` = 1

获取当前用户的文章,访问 articles(关联方法名) 属性即可,如下

<?phpnamespace app\api\controller;use app\api\model\User as UserModel;class User extends Base
{public function detail(){$user_id = 1;$detail = UserModel::getDetail($user_id);echo '<pre>';var_dump($detail->articles);echo '</pre>';}
}

输出如下

object(think\model\Collection)#50 (1) {["items":protected]=>array(2) {[0]=>object(app\api\model\Article)#45 (2) {["data"]=>array(6) {["article_id"]=>int(1)["title"]=>string(12) "测试标题"["content"]=>string(12) "测试内容"["user_id"]=>int(1)["create_time"]=>int(1689401566)["update_time"]=>int(1689401566)}["relation"]=>array(0) {}}[1]=>object(app\api\model\Article)#46 (2) {["data"]=>array(6) {["article_id"]=>int(2)["title"]=>string(13) "测试标题1"["content"]=>string(13) "测试内容1"["user_id"]=>int(1)["create_time"]=>int(1689498967)["update_time"]=>int(1689498967)}["relation"]=>array(0) {}}}
}

演示2

获取所有用户的用户详情以及用户的所有文章

用户 User 控制器

<?phpnamespace app\api\controller;use app\api\model\User as UserModel;class User extends Base
{// 获取所有用户的用户详情以及用户的所有文章public function list(){$list = UserModel::getList();echo '<pre>';var_dump($list);echo '</pre>';}
}

用户表 User 模型

<?phpnamespace app\api\model;class User extends Base
{protected $pk = 'user_id';// 获取所有用户的用户详情以及用户的所有文章public static function getList(){return self::with('articles')->select();}// 一对多获取用户的文章public function articles(){// 完整写法return $this->hasMany('Article', 'user_id', 'user_id');}
}

user 控制器  list 方法输出

object(think\model\Collection)#44 (1) {["items":protected]=>array(3) {[0]=>object(app\api\model\User)#41 (2) {["data"]=>array(4) {["user_id"]=>int(1)["name"]=>string(5) "admin"["create_time"]=>int(1688452509)["update_time"]=>int(1688452509)}["relation"]=>array(1) {["articles"]=>object(think\model\Collection)#52 (1) {["items":protected]=>array(2) {[0]=>object(app\api\model\Article)#47 (2) {["data"]=>array(6) {["article_id"]=>int(1)["title"]=>string(12) "测试标题"["content"]=>string(12) "测试内容"["user_id"]=>int(1)["create_time"]=>int(1689401566)["update_time"]=>int(1689401566)}["relation"]=>array(0) {}}[1]=>object(app\api\model\Article)#48 (2) {["data"]=>array(6) {["article_id"]=>int(2)["title"]=>string(13) "测试标题1"["content"]=>string(13) "测试内容1"["user_id"]=>int(1)["create_time"]=>int(1689498967)["update_time"]=>int(1689498967)}["relation"]=>array(0) {}}}}}}[1]=>object(app\api\model\User)#42 (2) {["data"]=>array(4) {["user_id"]=>int(2)["name"]=>string(0) ""["create_time"]=>int(1689732287)["update_time"]=>int(1689732287)}["relation"]=>array(1) {["articles"]=>object(think\model\Collection)#53 (1) {["items":protected]=>array(0) {}}}}[2]=>object(app\api\model\User)#43 (2) {["data"]=>array(4) {["user_id"]=>int(3)["name"]=>string(6) "测试"["create_time"]=>int(1690355199)["update_time"]=>int(1690355199)}["relation"]=>array(1) {["articles"]=>object(think\model\Collection)#54 (1) {["items":protected]=>array(0) {}}}}}
}

多条查询返回的是 Collection(结果集)对象,Collection 对象的 item 属性保存着所有用户模型实例,每个用户模型实例的 relation 属性 (关联数组)属性保存着关联模型实例,关联方法名 articles 作为键名,结果集对象作为键值,结果集对象的 items 属性(索引数组)保存着关联查询结果。

使用的 SQL 如下

SELECT * FROM `shop_user`SELECT * FROM `shop_article` WHERE `user_id` IN (1,2,3)

获取每个用户的所有文章,访问 articles(关联方法名) 属性即可,如下

<?phpnamespace app\api\controller;use app\api\model\User as UserModel;class User extends Base
{public function list(){$list = UserModel::getList();foreach ($list as $user) {echo '<pre>';var_dump($user->articles);echo '</pre>';}}}

​​​​​​​

user 控制器 list 方法输出如下

object(think\model\Collection)#52 (1) {["items":protected]=>array(2) {[0]=>object(app\api\model\Article)#47 (2) {["data"]=>array(6) {["article_id"]=>int(1)["title"]=>string(12) "测试标题"["content"]=>string(12) "测试内容"["user_id"]=>int(1)["create_time"]=>int(1689401566)["update_time"]=>int(1689401566)}["relation"]=>array(0) {}}[1]=>object(app\api\model\Article)#48 (2) {["data"]=>array(6) {["article_id"]=>int(2)["title"]=>string(13) "测试标题1"["content"]=>string(13) "测试内容1"["user_id"]=>int(1)["create_time"]=>int(1689498967)["update_time"]=>int(1689498967)}["relation"]=>array(0) {}}}
}
object(think\model\Collection)#53 (1) {["items":protected]=>array(0) {}
}
object(think\model\Collection)#54 (1) {["items":protected]=>array(0) {}
}

如果觉得作者写得好,请帮我点个赞,谢谢。

相关文章:

ThinkPHP 一对多关联

用一对多关联的前提 多的一方的数据库表有一的一方数据库表的外键。 举例&#xff0c;用户获取自己的所有文章 数据表结构如下 // 用户表 useruser_id - integer // 用户主键name - varchar // 用户名称// 文章表 articlearticle_id - integer // 文章主键title - varchar …...

C++基础篇(二)基本数组及示例

目录 一、一维数组1、定义和初始化2、访问和修改3、元素逆置和冒泡排序 二、二维数组&#xff08;用指针进行访问与修改&#xff09;1、定义和初始化2、访问与修改 三、更高维度的数组1、三维数组2、高维数组 一、一维数组 1、定义和初始化 在 C 中&#xff0c;可以使用下面的…...

C++多态练习题

目录 一.习题1&#xff1a; 解决下列测试代码所出现的问题 测试用例1&#xff1a; 测试用例2&#xff1a; 代码改进&#xff1a; 习题1总结&#xff1a; 二.习题2. 求类对象的大小 三.习题3&#xff1a; 代码解析 &#xff1a; 解析图&#xff1a; 四.习题4&#xff…...

ELD透明屏在智能家居中有哪些优点展示?

ELD透明屏是一种新型的显示技术&#xff0c;它能够在不需要背光的情况下显示图像和文字。 ELD透明屏的原理是利用电致发光效应&#xff0c;通过在透明基板上涂覆一层特殊的发光材料&#xff0c;当电流通过时&#xff0c;发光材料会发出光线&#xff0c;从而实现显示效果。 ELD…...

第十三章 利用PCA简化数据

文章目录 第十三章 利用PCA简化数据13.1降维技术13.2PCA13.2.1移动坐标轴 13.2.2在NumPy中实现PCA13.3利用PCA对半导体制造数据降维 第十三章 利用PCA简化数据 PCA&#xff08;Principal Component Analysis&#xff0c;主成分分析&#xff09;是一种常用的降维技术&#xff0…...

开源中文分词Ansj的简单使用

ANSJ是由孙健&#xff08;ansjsun&#xff09;开源的一个中文分词器&#xff0c;为ICTLAS的Java版本&#xff0c;也采用了Bigram HMM分词模型&#xff1a;在Bigram分词的基础上&#xff0c;识别未登录词&#xff0c;以提高分词准确度。 虽然基本分词原理与ICTLAS的一样&#…...

251_多线程_创建一个多线程的图像处理应用,其中每个线程负责对一部分图像进行处理,然后将处理后的结果合并为最终图像

举一个更丰富的例子来说明多线程的用法。 我们将创建一个多线程的图像处理应用,其中每个线程负责对一部分图像进行处理,然后将处理后的结果合并为最终图像。 这个例子可以更好地展示多线程并发处理的优势。 假设有一个函数 processImageSection,它会对图像的一个特定区域进…...

[吐槽Edge浏览器]关于Edge浏览器的闪退问题

这个浏览器嘛&#xff0c;在谷歌浏览器不能页面翻译后&#xff0c;一直是用的高高兴兴的&#xff0c;可突然有一天&#xff0c;Edge浏览器页面加载不出来了。 很慌&#xff0c;大概就是页面崩溃、加载失败什么的都出现过。 修了整整一天&#xff0c;不知道原因在哪&#xff0c;…...

数据包在网络中传输的过程

ref: 【先把这个视频看完了】&#xff1a;数据包的传输过程【网络常识10】_哔哩哔哩_bilibili 常识都看看 》Ref&#xff1a; 1. 这个写的嘎嘎好&#xff0c;解释了为啥4层7层5层&#xff0c;还有数据包封装的问题:数据包在网络中的传输过程详解_数据包传输_张孟浩_jay的博客…...

Acwing.875 快速幂

题目 给定n组ai , bi, pi&#xff0c;对于每组数据&#xff0c;求出akimod pi的值。 输入格式 第一行包含整数n。 接下来n行&#xff0c;每行包含三个整数ai , bi,pi。输出格式 对于每组数据&#xff0c;输出一个结果&#xff0c;表示aibimod pi的值。 每个结果占一行。 数…...

【决策树-鸢尾花分类】

决策树算法简介 决策树是一种基于树状结构的分类与回归算法。它通过对数据集进行递归分割&#xff0c;将样本划分为多个类别或者回归值。决策树算法的核心思想是通过构建树来对数据进行划分&#xff0c;从而实现对未知样本的预测。 决策树的构建过程 决策树的构建过程包括以…...

类与对象(中--构造函数)

类与对象&#xff08;中--构造函数&#xff09; 1、构造函数的特性2、默认构造函数3、编译器自动生成的默认构造函数&#xff08;无参的&#xff09;&#xff08;当我们不写构造函数时&#xff09;3.1 编译器自动生成的默认构造函数只对 自定义类型的成员变量 起作用&#xff0…...

Makefile学习1

文章目录 Makefile学习1Makefile简介Makefile重要性Makefile内容1) 显式规则2) 隐晦规则3) 变量的定义4) 文件指示5) 注释 Makefile规则规则默认目标多目标多规则目标伪目标 Makefile目标依赖头文件依赖自动生成头文件依赖关系 Makefile命令Makefile变量变量定义和使用赋值立即…...

城市内涝监测预警系统,科学“智治”应对灾害

近日&#xff0c;台风“杜苏芮”以摧枯拉朽之势给我国东南沿海地区带来狂风骤雨&#xff0c;福建的三个国家气象观测站日降水量突破历史极值。之后&#xff0c;“杜苏芮”一路北上。中央气象台预报称&#xff0c;7月29日至8月1日&#xff0c;北京、天津、河北、山东西部、河南北…...

切片[::-1]解析列表list表示的“非负整数加1”

列表数位表示非负整数&#xff0c;熟练操作“满十进位”。 (本笔记适合熟练操作Python列表list的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅…...

Mac下certificate verify failed: unable to get local issuer certificate

出现这个问题&#xff0c;可以安装证书 在finder中查找 Install Certificates.command找到后双击&#xff0c;或者使用其他终端打开 安装完即可...

Django项目启动错误

uwsgi项目启动错误信息如下Did you install mysqlclient?Command pkg-config --exists mysqlclient returned non-zero exit status 1Command pkg-config --exists mariadb returned non-zero exit status 1.Traceback (most recent call last):File "/home/dream21th/co…...

Vue2 第十二节 Vue组件化编程 (二)

1. VueComponent 2. 单文件组件 一. VueComponent 组件本质上是一个名为VueComponent的构造函数&#xff0c;不是程序员定义的&#xff0c;是Vue.extend生成的只需要写<school/>或者<school><school/>&#xff0c;Vue解析时&#xff0c;会帮我们创建schoo…...

pycharm 远程连接服务器并且debug, 支持torch.distributed.launch debug

未经允许&#xff0c;本文不得转载&#xff0c;vx&#xff1a;837007389 文章目录 step1&#xff1a;下载专业版本的pycharmstep2 配置自动同步文件夹&#xff0c;即远程的工程文件和本地同步2.1 Tools -> Deployment -> configuration2.2 设置同步文件夹2.3 同步服务器…...

SAP ABAP 基础语法超详细

1&#xff0e;表声明 Tables: 表名[,表名]. 声明多个表时可用逗号分隔当你声明了一个数据表的同时&#xff0c;系统也同时自动生成了一个和数据表同名的结构&#xff0c;结构的变量集等于数据表里面的字段。 2&#xff0e;定义变量 Data: v1[(l)] [type t] [decimals d] [v…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...