ThinkPHP 一对多关联

news2024/9/25 7:25:35

用一对多关联的前提

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

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

数据表结构如下

// 用户表
user
    user_id - integer  // 用户主键
    name - varchar // 用户名称



// 文章表
article
    article_id - integer // 文章主键
    title - varchar // 文章名标题
    content - text // 文章内容
    user_id - integer // 作者 user_id
 
 

 
 
 

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

一对多关联定义

用户表 user 模型:

<?php

namespace 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 控制器

<?php

namespace 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 模型

<?php

namespace 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 1

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

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

<?php

namespace 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 控制器

<?php

namespace 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 模型

<?php

namespace 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(关联方法名) 属性即可,如下

<?php

namespace 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) {
  }
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/796753.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WSL2安装google chrome浏览器

一. 环境: Windows 11 Ubuntu-22.04 二. 安装google-chrome步骤&#xff08;官方文档&#xff09;&#xff1a; 1. 创建文件夹&#xff1a;mkdir chrome 2. 进入目录&#xff1a;cd chrome/ 3. 下载chrome压缩包&#xff1a;sudo wget https://dl.google.com/linux/direct/go…

学习 NestJs 的第一步

安装 NestJS 的先决条件和安装 NestJS NodeJS 的版本需要大于等于 16。 安装 NestJS 的命令是&#xff1a;npm i -g nestjs/cli。 使用命令创建项目 使用 nest new <项目名称> 来创建项目&#xff0c;假如要开启 TS 的严格语法功能的话&#xff0c;可以把--strict 标…

【雕爷学编程】Arduino动手做(93)--- 0.96寸OLED液晶屏模块15

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

OSPF的拓展配置

OSPF的拓展配置 1.手工认证 --- 在OSPF数据包交互中&#xff0c;邻居之间的数据报中将携带认证口令&#xff0c;两边认证口令相同&#xff0c;则意味着身份合法 OSPF的手工认证总共分为三种&#xff1a; 1.接口认证 [r5-GigabitEthernet0/0/0]ospf authenticati…

GB/T 25000.51解读——软件产品的性能效率怎么测?

GB/T 25000.51-2016《软件产品质量要求和测试细则》是申请软件检测CNAS认可一定会用到的一部国家标准。在前面的文章中&#xff0c;我们为大家整体介绍了GB/T 25000.51-2016《软件产品质量要求和测试细则》国家标准的结构和所涵盖的内容以及对软件产品的八大质量特性中的功能性…

fastposter v2.16.0 让海报开发更简单

fastposter v2.16.0 让海报开发更简单 &#x1f525;&#x1f525;&#x1f525; fastposter海报生成器是一款快速开发海报的工具。只需上传一张背景图&#xff0c;在对应的位置放上组件&#xff08;文字、图片、二维&#x1f434;、头像&#xff09; 点击代码直接生成各种语言…

个人信息的编写以及头像的联动

下面这个是导航栏通过on触发的事件 与图片联动 <template><div><ul><li>{{obj.account}}</li><li>{{obj.ctime|dataFormat}}</li><li>{{obj.id}}</li><li>{{obj.userGroup}}</li><div><!-- acti…

VIOOVI精益管理:实现高效运营和持续改进的关键

关于什么是精益化管理这个问题&#xff0c;从字面上理解&#xff0c;“精”为“精良”&#xff0c;“益”为“利益”&#xff0c;意在产品更加精良&#xff0c;利益更加丰厚。而从丰田精益生产中我们可以看出精益化管理绝不是以偏概全的管理&#xff0c;而是全面的结合内部、外…

Linux操作系统~必考面试题⑧

1、pwd 命令 pwd 命令用于查看当前工作目录路径。 实例&#xff1a; 查看当前路径 pwd 查看软链接的实际路径 pwd -P 2、rmdir 命令 从一个目录中删除一个或多个子目录项&#xff0c;删除某目录时也必须具有对其父目录的写权限。 注意&#xff1a;不能删除非空目录实例&…

Java面试笔记

JAVA基础知识 语法结构 1.类 2.属性 3.方法 4.静态代码块 构造器 构造函数&#xff0c;构造类的对象&#xff0c;默认隐式&#xff0c;创建对象&#xff0c;先执行父类构造函数&#xff0c;再执行子类构造函数 父类的super必须在第一行 代码块 优先级最高&#xff0c;只…

pyspark笔记:读取 处理csv文件

pyspark cmd上的命令 1 读取文件 1.1 基本读取方式 注意读取出来的格式是Pyspark DataFrame&#xff0c;不是DataFrame&#xff0c;所以一些操作上是有区别的 1.1.1 format DataFrame spark.read.format("csv").option(name,value).load(path) format表示读取…

硬盘数据恢复怎么做?5步快速恢复数据!

“我的电脑刚买回来没多久&#xff0c;不知为啥硬盘就出现问题了&#xff0c;我很多的数据都丢失了&#xff0c;这种情况进行硬盘数据恢复还有希望吗&#xff1f;希望各位老师给我点意见&#xff01;感谢&#xff01;” 在数字化时代&#xff0c;数据已经成为我们生活中不可或缺…

美团面试官热爱考察的问题:你真的会判断链表环吗?

大家好&#xff0c;我是小米&#xff01;今天我要和大家一起来解析美团面试中经常会遇到的一道经典问题&#xff1a;如何判断链表是否为环形链表&#xff1f;这是一道考察数据结构与算法基础的问题&#xff0c;也是面试中的常客。相信通过这篇文章的学习&#xff0c;你将能够更…

【决策树-鸢尾花分类】

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

C#,中国福利彩票《刮刮乐》的数学算法(02)——时来运转

1 中国福利彩票 中国福利彩票始于1987年7月27日&#xff0c;以“团结各界热心社会福利事业的人士&#xff0c;发扬社会主义人道主义精神&#xff0c;筹集社会福利资金&#xff0c;兴办残疾人、老年人、孤儿福利事业和帮助有困难的人”、即“扶老、助残、救孤、济困”为宗旨。随…

儿童小学生护眼灯选哪个牌子经济好用?分享五款好用的台灯

近期&#xff0c;经济好用的护眼台灯赶上了热潮&#xff0c;许多家长反应不知道怎么选一款合适有经济的护眼台灯&#xff1f;面对市场上很多鱼龙混杂的台灯&#xff0c;真的是眼花缭乱&#xff0c;选台灯不一定要选贵的&#xff0c;但一定要选对的&#xff0c;今天小编就分享五…

网页开发基础——HTML

一、flask框架 Flask是一种轻量级的Python web应用程序框架&#xff0c;可以帮助使用者快速构建Web应用程序和API。由于其简洁、灵活和易于上手的特点&#xff0c;Flask被广泛用于开发小型到中型的Web应用程序和后端API。本次我们主要是使用flask框架&#xff0c;进行一个小型w…

Git链接上游仓库

技术背景 在Git的操作过程中&#xff0c;一般的组织内部工作模式可以在同一个仓库上的master-develop-feature不同分支上进行开发&#xff0c;也有一些人和外部协作者会通过Fork到自己本地的仓库进行更新的方案。但是对于Fork仓库的更新有一个问题是&#xff0c;如果长期在自己…

【React Native】学习记录(一)——环境搭建

Expo是一套工具&#xff0c;库和服务&#xff0c;可让您通过编写JavaScript来构建原生iOS和Android应用程序。 一开始学习的时候直接使用的是expo。 npx create-expo-app my-appcd my-appnpm run start接下来需要搭建安卓和IOS端&#xff08;为此特意换成了苹果电脑&#xff09…

AArch64异常模型

概述 AArch64 异常模型指南介绍了 Armv8‑A 和 Armv9‑A 中的异常和特权模型。它涵盖了 Arm 架构中不同类型的异常&#xff0c;以及与异常相关的处理器行为。 这些内容适用于底层代码&#xff08;例如boot code或kernel&#xff09;开发人员&#xff0c;对于配置或者管理异常…