ThinkPHP 一对多关联

用一对多关联的前提

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

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

数据表结构如下

// 用户表
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) {
  }
}

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThinkPHP6中,实现一对多关联查询的方法是使用hasMany模式。具体设置方式如下: 1. 在主表的模型中使用hasMany方法进行关联设置: ``` public function 附表名() { return $this->hasMany(附表模型::class, '外键字段', '主键字段'); } ``` 例如: ``` public function profile() { return $this->hasMany(Profile::class, 'user_id', 'id'); } ``` 2. 进行一对多关联查询: ``` $user = UserModel::find(主表记录的id); return json($user->附表关联方法名); ``` 例如: ``` $user = UserModel::find(19); return json($user->profile); ``` 3. 进行数据筛选查询: ``` $user->附表关联方法名->where('条件字段', '条件操作符', '条件值'); ``` 例如: ``` $user->profile->where('id', '>=', 10); ``` 4. 使用has()方法查询满足条件的主表记录: ``` UserModel::has('附表关联方法名', '条件操作符', '条件值')->select(); ``` 例如: ``` UserModel::has('profile', '>=', 2)->select(); ``` 5. 使用together()方法,在删除主表记录时,同时删除关联的附表记录: ``` $user = UserModel::with('附表关联方法名')->find(主表记录的id); $user->together(['附表关联方法名'])->delete(); ``` 例如: ``` $user = UserModel::with('profile')->find(22); $user->together(['profile'])->delete(); ``` 以上就是在ThinkPHP6中实现一对多关联查询的方法。希望对你有所帮助。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值