• ThinkPHP的模型关联(多对多关联)


    关联定义

    多对多关联不像一对一和一对多关联,它还要多建一个中间表用来处理多对多的关联,例如:

    #城市
    create table city
    (
        c_id int primary key AUTO_INCREMENT comment "编号",
        c_name varchar(255) comment '城市名称'
    )
    
    #区域(别名)
    create table  area
    (
        a_id int primary key AUTO_INCREMENT comment "编号",
        a_name varchar(255) comment '区域名称'
    )
    
    #中间表(枢纽表)
    create table  city_area
    (
        id int primary key AUTO_INCREMENT comment "编号",
        aid int comment '区域外键',
        cid int comment '城市外键'
    )

    一个区域(别名)有多座城市,一座城市有多个区域(别名),例如:广州即属于一线城市,也是珠三角地区,同时它还叫“羊城”;而珠三角地区包括的城市有广州、佛山、肇庆、深圳、东莞、惠州等。

    下面使用belongsToMany关联中间表,city(城市)模型:

    <?php
    
    namespace appdemomodel;
    use thinkModel;
    
    class City extends Model    //城市表
    {
        public function area(){
            //belongsToMany('区域模型','中间表名','外键名','外键名');
            return $this->belongsToMany('Area','city_area','aid','cid');
        }
    }

    注:belongsToMany后面两个一定要对应中间表外键的顺序

     area(区域)模型:

    class Area  extends Model   //全国区域表
    {
        public function city(){
            //belongsToMany('城市模型','中间表名','外键名','外键名');
            return $this->belongsToMany("City",'city_area','aid','cid');
        }
    
         public function city(){
            //belongsToMany('城市模型','中间表名');  这种也一样
            return $this->belongsToMany("City",'city_area');
        }
    }

    中间表模型可以不需要建立

    关联查询

    我们可以通过下面的方式获取关联数据

            $city = City::get(1);
            foreach($city->area as $role){
                // 获取城市id为1的所有区域名称
                dump($role->a_name);
            }

    如果要获取中间表数据,可以使用

            $city = City::get(1);
            foreach($city->area as $role){
                // 获取中间表数据
                print_r($role->pivot);
            }

    关联新增

            //关联单条新增
            $city = City::get(1);
            //增加关联数据 会自动写入中间表数据
            $city->area()->save(['a_name'=>'珠三角地区']);
            //批量新增
            $city->area()->saveAll([
                ['a_name'=>'一线城市'],
                ['a_name'=>'羊城'],
            ]);    

    只新增中间表数据,可以使用

            //方法一:添加中间表数据
            $city = City::get(1);
            //条件查询,找出珠三角地区
            $area = Area::getByAName("珠三角地区");
            //使用attach方法增加中间表的数据
            $city->area()->attach($area);//新增数据:城市的id为1,区域为珠三角地区的id*/
            
            //方法二:,效果等同方法一
            $city = City::get(1);
            $city->area()->attach(2);//新增数据:城市的id为1,区域为2    

    下面是新增中间表方法二执行的SQL语句:

    INSERT INTO `city_area` (`cid` , `aid`) VALUES (1 , 2)

    关联删除

    只删除中间表数据,但不删关联模型的数据

            //方法一:
            $city = City::get(1);
            $area = Area::getByAName("珠三角地区");
            //关联删除数据,但不删关联模型的数据
            $city->area()->detach($area);
    
            //方法二
            $city = City::get(1);
            //DELETE FROM `city_area` WHERE `cid` = 1 AND `aid` = 1
            $city->area()->detach(1);
    
            //批量删除
            $city->area()->detach([1]);    

    删除中间表方法二执行的SQL:

    DELETE FROM `city_area` WHERE `cid` = 1 AND `aid` = 1

    如果有必要,也可以删除中间表的数据同时删除关联模型

            $city = City::get(1);
            $area = Area::getByAName("羊城");
            //这里不光删除中间表,也删除羊城
            $city->area()->detach($area,true);    
  • 相关阅读:
    《高性能MySQL》读书笔记--Schema与数据类型优化
    小程序从零开始 新手必看(2)
    小程序从零开始 新手必看(1)
    Web 前端
    摒弃 react-redux: 非侵入式状态共享实现
    Web 前端
    Web 前端
    Web 前端
    vue实现打印、批量打印
    JS脱敏带表情的字符串
  • 原文地址:https://www.cnblogs.com/bushui/p/11903703.html
Copyright © 2020-2023  润新知