ThinkPHP 多对多关联

news2024/11/25 16:25:20

用多对多关联的前提

如果模型 A 多对多关联模型 C,必须存在一张中间表 B 记录着双方的主键,因为就是靠着这张中间表 B 记录着模型 A 与模型 C 的关系。

举例,数据表结构如下

// 商品表
goods
    goods_id - integer // 商品主键
    goods_name - varchar // 商品名称
     

// 分类表
category
    category_id - integer // 分类主键
    name - varchar // 分类名称


// 商品分类关系表
goods_category_rel
    id - integer // 主键
    goods_id - integer // 商品表主键的外键
    category_id - integer // 分类表主键的外键

如果按以前的数据表设计,商品表与分类表不是这样设计的,而是 goods 表有一个 category_id 字段,该字段保存 category 表的 category_id,这样每个商品都对应着一个分类,比如荔枝的分类是水果,但这样的设计缺点也是显而易见的,一个商品只能有一个分类,比如荔枝的分类只能是水果,但如果把数据库设计成上面这样的结构,荔枝的分类就可以有多个,比如除了水果,还能是特价产品,或者是其它分类等等。

多对多关联定义

商品表模型:

<?php

namespace app\api\model;

class Goods extends Base
{

    protected $pk = 'goods_id';

    protected $hidden = ['create_time', 'update_time'];

    // 获取商品的分类
    public function category()
    {
        // Goods 模型多对多关联 Category 模型
        return $this->belongsToMany('Category', 'GoodsCategoryRel');
        // 完整写法
        // return $this->belongsToMany('Category', 'GoodsCategoryRel', 'category_id', 'goods_id');
    }


}

 belongsToMany 方法的参数如下:

belongsToMany('关联模型', '中间模型', '外键1', '外键2');

  • 关联模型(必须):模型名或者模型类名
  • 中间模型:默认规则是当前模型名+_+关联模型名 (可以指定模型名)
  • 外键1:关联模型在中间表的外键,默认的外键名规则是关联模型名+_id
  • 外键2:当前模型在中间表的外键,默认规则是当前模型名+_id

中间表模型

<?php

namespace app\api\model;

class GoodsCategoryRel extends Base
{
    protected $hidden = ['create_time', 'update_time'];
}

分类表模型

<?php

namespace app\api\model;

class Category extends Base
{
    // 因为不是默认主键所以要重新定义
    protected $pk = 'category_id';

    protected $hidden = ['create_time', 'update_time'];
   
}

实例演示

shop_goods 表

 shop_category 表

shop_goods_category_rel 表

演示1

获取 goods_id 为 1 的商品详情以及它的分类

Goods 控制器

<?php

namespace app\api\controller;

use app\api\model\Goods as GoodsModel;

class Goods extends Base
{
    // 获取 goods_id 等于 1 的商品详情
    public function detail()
    {
        $goods_id = 1;

        $detail = GoodsModel::getDetail($goods_id);

        halt($detail);

    }
}

Goods 模型

<?php

namespace app\api\model;

class Goods extends Base
{
    // 因为不是默认主键名称,所以要重新定义
    protected $pk = 'goods_id';

    protected $hidden = ['create_time', 'update_time'];

    // 获取商品详情
    public static function getDetail($goods_id)
    {    
        // 关联预载入查询
        // 第二个参数是所用到的关联方法的方法名
        return self::get($goods_id, 'category');
    }

    // 多对多关联获取商品的所有分类
    public function category()
    {
        return $this->belongsToMany('Category', 'GoodsCategoryRel');
        // 完整写法
        // return $this->belongsToMany('Category', 'GoodsCategoryRel', 'category_id', 'goods_id');
    }
}

Goods 控制器  detail 方法输出

array(7) {
  ["goods_id"] => int(10001)
  ["goods_name"] => string(12) "桂味荔枝"
  ["stock_total"] => int(0)
  ["status"] => int(10)
  ["sort"] => int(0)
  ["is_delete"] => int(0)
  ["category"] => object(think\Collection)#50 (1) {
    ["items":protected] => array(2) {
      [0] => object(app\api\model\Category)#41 (2) {
        ["data"] => array(8) {
          ["category_id"] => int(6)
          ["name"] => string(12) "新鲜水果"
          ["parent_id"] => int(1)
          ["image_id"] => int(0)
          ["status"] => int(1)
          ["sort"] => int(0)
          ["create_time"] => int(1688454738)
          ["update_time"] => int(1688454738)
        }
        ["relation"] => array(1) {
          ["pivot"] => object(think\model\Pivot)#51 (2) {
            ["data"] => array(5) {
              ["id"] => int(1001)
              ["goods_id"] => int(10001)
              ["category_id"] => int(6)
              ["create_time"] => int(1688696518)
              ["update_time"] => int(1688696518)
            }
            ["relation"] => array(0) {
            }
          }
        }
      }
      [1] => object(app\api\model\Category)#47 (2) {
        ["data"] => array(8) {
          ["category_id"] => int(10)
          ["name"] => string(12) "特价产品"
          ["parent_id"] => int(1)
          ["image_id"] => int(0)
          ["status"] => int(1)
          ["sort"] => int(0)
          ["create_time"] => int(1688454870)
          ["update_time"] => int(1688454870)
        }
        ["relation"] => array(1) {
          ["pivot"] => object(think\model\Pivot)#52 (2) {
            ["data"] => array(5) {
              ["id"] => int(1002)
              ["goods_id"] => int(10001)
              ["category_id"] => int(10)
              ["create_time"] => int(1688795635)
              ["update_time"] => int(1688795635)
            }
            ["relation"] => array(0) {
            }
          }
        }
      }
    }
  }
}

关联方法名 category 作为键名,关联查询结果集对象 Collection 作为键值。

获取当前商品的分类,访问 category(关联方法名) 属性即可,如下

<?php

namespace app\api\controller;

use app\api\model\Goods as GoodsModel;

class Goods extends Base
{
    public function detail()
    {
        $goods_id = 10001;

        $detail = GoodsModel::get($goods_id);

        $categories  = $detail->category;

        halt($categories);

    }
}

输出

object(think\Collection)#47 (1) {
  ["items":protected] => array(2) {
    [0] => object(app\api\model\Category)#41 (2) {
      ["data"] => array(8) {
        ["category_id"] => int(6)
        ["name"] => string(12) "新鲜水果"
        ["parent_id"] => int(1)
        ["image_id"] => int(0)
        ["status"] => int(1)
        ["sort"] => int(0)
        ["create_time"] => int(1688454738)
        ["update_time"] => int(1688454738)
      }
      ["relation"] => array(1) {
        ["pivot"] => object(think\model\Pivot)#50 (2) {
          ["data"] => array(5) {
            ["id"] => int(1001)
            ["goods_id"] => int(10001)
            ["category_id"] => int(6)
            ["create_time"] => int(1688696518)
            ["update_time"] => int(1688696518)
          }
          ["relation"] => array(0) {
          }
        }
      }
    }
    [1] => object(app\api\model\Category)#46 (2) {
      ["data"] => array(8) {
        ["category_id"] => int(10)
        ["name"] => string(12) "特价产品"
        ["parent_id"] => int(1)
        ["image_id"] => int(0)
        ["status"] => int(1)
        ["sort"] => int(0)
        ["create_time"] => int(1688454870)
        ["update_time"] => int(1688454870)
      }
      ["relation"] => array(1) {
        ["pivot"] => object(think\model\Pivot)#51 (2) {
          ["data"] => array(5) {
            ["id"] => int(1002)
            ["goods_id"] => int(10001)
            ["category_id"] => int(10)
            ["create_time"] => int(1688795635)
            ["update_time"] => int(1688795635)
          }
          ["relation"] => array(0) {
          }
        }
      }
    }
  }
}

演示2

获取所有的商品详情以及它的分类

Goods 控制器

<?php

namespace app\api\controller;

use app\api\model\Goods as GoodsModel;

class Goods extends Base
{
    // 获取所有商品
    public function getList()
    {
        $goodsList = GoodsModel::getList();
        halt($goodsList);
    }
}

Goods 模型

<?php

namespace app\api\model;

class Goods extends Base
{

    protected $pk = 'goods_id';

    protected $hidden = ['create_time', 'update_time'];

    // 获取所有商品列表
    public static function getList()
    {
        // 关联预载入
        // 参数为所用到的关联方法
        return self::with(['category'])
            ->select();
    }

    // 多对多获取商品分类
    public function category()
    {
        return $this->belongsToMany('Category', 'GoodsCategoryRel');
        // 完整写法
        // return $this->belongsToMany('Category', 'GoodsCategoryRel', 'category_id', 'goods_id');
    }
}

输出

object(think\Collection)#40 (1) {
  ["items":protected] => array(1) {
    [0] => object(app\api\model\Goods)#42 (2) {
      ["data"] => array(8) {
        ["goods_id"] => int(10001)
        ["goods_name"] => string(12) "桂味荔枝"
        ["stock_total"] => int(0)
        ["status"] => int(10)
        ["sort"] => int(0)
        ["is_delete"] => int(0)
        ["create_time"] => int(1688696518)
        ["update_time"] => int(1688696518)
      }
      ["relation"] => array(1) {
        ["category"] => object(think\Collection)#50 (1) {
          ["items":protected] => array(2) {
            [0] => object(app\api\model\Category)#41 (2) {
              ["data"] => array(8) {
                ["category_id"] => int(6)
                ["name"] => string(12) "新鲜水果"
                ["parent_id"] => int(1)
                ["image_id"] => int(0)
                ["status"] => int(1)
                ["sort"] => int(0)
                ["create_time"] => int(1688454738)
                ["update_time"] => int(1688454738)
              }
              ["relation"] => array(1) {
                ["pivot"] => object(think\model\Pivot)#51 (2) {
                  ["data"] => array(5) {
                    ["id"] => int(1001)
                    ["goods_id"] => int(10001)
                    ["category_id"] => int(6)
                    ["create_time"] => int(1688696518)
                    ["update_time"] => int(1688696518)
                  }
                  ["relation"] => array(0) {
                  }
                }
              }
            }
            [1] => object(app\api\model\Category)#47 (2) {
              ["data"] => array(8) {
                ["category_id"] => int(10)
                ["name"] => string(12) "特价产品"
                ["parent_id"] => int(1)
                ["image_id"] => int(0)
                ["status"] => int(1)
                ["sort"] => int(0)
                ["create_time"] => int(1688454870)
                ["update_time"] => int(1688454870)
              }
              ["relation"] => array(1) {
                ["pivot"] => object(think\model\Pivot)#52 (2) {
                  ["data"] => array(5) {
                    ["id"] => int(1002)
                    ["goods_id"] => int(10001)
                    ["category_id"] => int(10)
                    ["create_time"] => int(1688795635)
                    ["update_time"] => int(1688795635)
                  }
                  ["relation"] => array(0) {
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

每个商品模型的 relation (关联数组)属性保存着关联模型,关联方法名 category 作为键名,结果集对象作为键值,结果集对象的 items 属性(数组)保存着关联查询结果。

获取每个商品的分类,访问 category(关联方法名) 属性即可,如下

<?php

namespace app\api\controller;

use app\api\model\Goods as GoodsModel;

class Goods extends Base
{
    public function getList()
    {
        $goodsList = GoodsModel::getList();
        foreach($goodsList as $value){
            dump($value->category);
        }

    }

}

Goods 模型 getList 方法输出

object(think\Collection)#50 (1) {
  ["items":protected] => array(2) {
    [0] => object(app\api\model\Category)#41 (2) {
      ["data"] => array(8) {
        ["category_id"] => int(6)
        ["name"] => string(12) "新鲜水果"
        ["parent_id"] => int(1)
        ["image_id"] => int(0)
        ["status"] => int(1)
        ["sort"] => int(0)
        ["create_time"] => int(1688454738)
        ["update_time"] => int(1688454738)
      }
      ["relation"] => array(1) {
        ["pivot"] => object(think\model\Pivot)#51 (2) {
          ["data"] => array(5) {
            ["id"] => int(1001)
            ["goods_id"] => int(10001)
            ["category_id"] => int(6)
            ["create_time"] => int(1688696518)
            ["update_time"] => int(1688696518)
          }
          ["relation"] => array(0) {
          }
        }
      }
    }
    [1] => object(app\api\model\Category)#47 (2) {
      ["data"] => array(8) {
        ["category_id"] => int(10)
        ["name"] => string(12) "特价产品"
        ["parent_id"] => int(1)
        ["image_id"] => int(0)
        ["status"] => int(1)
        ["sort"] => int(0)
        ["create_time"] => int(1688454870)
        ["update_time"] => int(1688454870)
      }
      ["relation"] => array(1) {
        ["pivot"] => object(think\model\Pivot)#52 (2) {
          ["data"] => array(5) {
            ["id"] => int(1002)
            ["goods_id"] => int(10001)
            ["category_id"] => int(10)
            ["create_time"] => int(1688795635)
            ["update_time"] => int(1688795635)
          }
          ["relation"] => array(0) {
          }
        }
      }
    }
  }
}

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

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

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

相关文章

【C#】并行编程实战:使用延迟初始化提高性能

在前面的章节中讨论了 C# 中线程安全并发集合&#xff0c;有助于提高代码性能、降低同步开销。本章将讨论更多有助于提高性能的概念&#xff0c;包括使用自定义实现的内置构造。 毕竟&#xff0c;对于多线程编程来讲&#xff0c;最核心的需求就是为了性能。 延迟初始化 - .NET…

手机怎么编辑pdf?这几款工具可以实现

手机怎么编辑pdf&#xff1f;在如今的数字时代&#xff0c;PDF文档已经成为了一种标准的文件格式。然而&#xff0c;当我们需要编辑这些PDF文档时&#xff0c;我们往往需要使用电脑上的专业软件&#xff0c;这给我们带来了很大的不便。不过&#xff0c;有许多手机应用程序可以让…

AIGC 大模型纷纷部署,企业如何为 AI 数据降本增效

编辑 | 宋慧 出品 | CSDN 云计算 AIGC 从年初开始持续爆火&#xff0c;国内各种大模型纷纷涌现&#xff0c;其中模型参数轻松突破千亿数量级。模型中数据的形态、部署也是多种多样的&#xff0c;庞大数据量背后的管理和成本不容小觑。 混合数据厂商肯睿 Cloudera 今年相继发布…

设计模式的概述

目录 分类 创建型模式 结构型模式 行为型模式 类之间的关系 关联关系 聚合关系 组合关系 依赖关系 继承关系 实现关系 设计原则 开闭原则 里氏代换原则 依赖倒转原则 接口隔离原则 合成复用原则 一、分类 创建型模式 用于描述“怎样创建对象”&#xff0c;它…

线程池的学习(一)

转载&#xff1a;Java 线程池 线程池的创建方式 方式一&#xff1a;创建单一线程的线程池 newSingleThreadExecutor 特点&#xff1a; 线程池中只包含 1 个线程&#xff0c;存活时间是无限的按照提交顺序执行任务唯一线程繁忙时&#xff0c;新提交的任务会被加入到阻塞队列…

Java springBoot项目报LDAP health check failed

报错内容如下&#xff1a; 在bootstrap.yml文件里加 management:health:ldap:enabled: false 配置。 或者在application.properties文件里加&#xff1a; management.health.ldap.enabledfalse 参考答案&#xff1a;LDAP health check failed 难道没有人遇到这样的问题吗&…

我造了一个新的词汇:信息湍流

信息湍流 信息湍流的简介起因有出现信息湍流的领域如何做信息湍流的计算 信息湍流的简介 在物流学中&#xff0c;一个物体从一个位置到另外一个位置&#xff0c;我们可以通过精确的公式计算来预测出新位置。 而水和气体则是大量一个一个物体组成的新物体&#xff0c;称为&…

Docker安装以及基础镜像的使用

Docker 安装 Docker 要求 CentOS 系统的内核版本高于 3.10 uname -r使用 root 权限登录 su # 输入密码更新 yum yum -y update卸载旧版本的 docker yum remove ‐y docker*安装需要的软件包 yum -y install yum-utils设置 yum 源&#xff0c;并更新 yum 包的索引 yum-config-ma…

凝心聚力,同为科技(TOWE)2023年中会议暨团建活动圆满举行

01凝心聚力 奋勇冲刺——年中会议现场 年中会议现场 时光冉冉&#xff0c;2023年已过半&#xff0c;7月4日-11日&#xff0c;为回望过往、总结成果、复盘经验&#xff0c;确保顺利完成公司年度目标&#xff0c;增强团队凝聚力、激发员工活力&#xff0c;深化企业文化建设&…

15 - 堆栈 - 大顶堆

前面我们学习了小顶堆,相信大家都已经有点概念了,今天来了解一下大顶堆。 大顶堆示意图 堆数组存放的公式 我们用简单的公式来描述一下堆的定义就是: 大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] 小顶堆:arr[i] <= arr[2i+1] && a…

两股热潮如何汇聚:当数字孪生遇上元宇宙

引言 随着科技的迅猛发展&#xff0c;数字孪生和元宇宙已成为当今技术界备受关注的两股热潮。这两个概念各自都在不同领域取得了突破性进展&#xff0c;但在最近的发展中&#xff0c;人们开始发现它们之间存在着潜在的契合点。本文将探讨数字孪生和元宇宙的定义、特点&#xf…

【【51单片机蜂鸣器实现起风了】】

哀伤如同风&#xff0c;消失无影踪。 前面的有两个非常关键的点希望兄弟们明白 我一开始也失算了 这里兄弟们注意务必改成int 不然会超出 就会出现播放一半从头开始的情况 下面是两份起风了代码直接附上main.c 因为另外的其实和我之前说的模板都一样复制粘贴就行 为什么是…

M1 Mac如何安装CentOS7虚拟机(图文详细解说)

1、下载相应的文件 2、打开VMware Fusion pro进行安装 3、 输入许可证密钥 4、 将CentOS-7拖入“从光盘或映像中安装”中 5、点击继续 6、选择其他-->其他64位ARM-->继续 7、进行自定设置 8、这里更改名为“Centos7”&#xff08;不要加空格&#xff09;&#xff0c;存…

2023 Testing Expo倒计时-聚焦Softing 9003展位

请点击此处&#xff0c;即可进行在线登记报名并了解更多信息&#xff01;

ES系列--文档处理

一、文档冲突 当我们使用 index API 更新文档 &#xff0c;可以一次性读取原始文档&#xff0c;做我们的修改&#xff0c;然后重 新索引 整个文档 。 最近的索引请求将获胜&#xff1a;无论最后哪一个文档被索引&#xff0c;都将被唯一存 储在 Elasticsearch 中。如果其他人同时…

Java-生成数据库设计文档

目录 场景screw 官网介绍接口编写 场景 在企业开发中&#xff0c;有些公司会要求开发人员编写数据库表结构文档&#xff0c;这项工作没啥技术含量而且很繁琐&#xff0c;每当有表发生更改时就需要维护这个文档&#xff0c;或者是需要交付数据库设计文档和导出数据库设计文档这类…

8月|龙讯旷腾高性能计算与工业材料模拟论坛2023

2023年8月25日 山东青岛 高性能计算与工业材料模拟论坛2023 青岛&#xff0c;别称岛城&#xff0c;国务院批复确定的中国沿海重要中心城市和滨海度假旅游城市&#xff0c;国家历史文化名城、中国帆船之都、世界啤酒之城、联合国电影之都&#xff0c;也是国家海洋科研和教育中…

【产品经理】TO B市场分析

市场分析是一个独立而又宏大的学科领域&#xff0c;并且具体使用中&#xff0c;目标和个体不同&#xff0c;分析的方式方法也不同。TO B产品的市场分析是对市场环境、市场规模、性质、特征、竞品进行分析&#xff0c;从而寻找和研究潜在需求的市场机会&#xff0c;帮助产品经理…

设计模式大白话——工厂模式

文章目录 设计模式大白话——工厂模式1.1、简单工厂:1.2、工厂方法1.3、抽象工厂 设计模式大白话——工厂模式 1.1、简单工厂: 场景与思路 ​ 现在需要开一个 Pizza 店&#xff0c;Pizza 店可以生产各种口味的 Pizza ​ 既然要生产各种各样的 Pizza&#xff0c;那就会很容易想…

管理类联考——英语——趣味篇——不择手段——d开头单词

&#x1f3e0;个人主页&#xff1a;fo安方的博客✨ &#x1f482;个人简历&#xff1a;大家好&#xff0c;我是fo安方&#xff0c;考取过HCIE Cloud Computing、CCIE Security、CISP、RHCE、CCNP RS、PEST 3等证书。&#x1f433; &#x1f495;兴趣爱好&#xff1a;b站天天刷&…