You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Yii2 API中获取包含关联用户数据的客户端列表?

Yii2 API返回包含关联用户数据的客户端列表实现方案

问题描述

需要在Yii2 API中返回如下格式的响应,每个客户端数据包含其关联的用户数据:

示例响应结构:

{
  "clients": [
    {
      "id": 1,
      "name": "client_1",
      "users": [
        {"id": 1, "name": "user_1", "clients_id": 1},
        {"id": 2, "name": "user_2", "clients_id": 1}
      ]
    },
    {
      "id": 2,
      "name": "client_2",
      "users": [
        {"id": 3, "name": "user_3", "clients_id": 2},
        {"id": 4, "name": "user_4", "clients_id": 2}
      ]
    }
  ]
}

请问如何编写对应的Yii2代码?是否可以使用Query Builder,还是需要使用MySQL语法?

实现方案

方法一:使用ActiveRecord关联(推荐)

这是Yii2中最简洁高效的方式,前提是已定义Client和User模型,并配置好关联关系。

  1. 定义模型关联
    在Client模型中添加关联方法,指定与User表的关联规则:
// models/Client.php
public function getUsers()
{
    // 假设User表外键为clients_id,关联到Client表的id字段
    return $this->hasMany(User::class, ['clients_id' => 'id']);
}
  1. 控制器中查询并返回数据
    在API控制器的动作方法中,通过with()预加载关联数据,避免N+1查询问题:
// controllers/Api/ClientController.php
public function actionIndex()
{
    // 查询所有客户端,并预加载关联的用户数据
    $clients = Client::find()->with('users')->all();
    
    // 设置响应格式为JSON并返回
    Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    return [
        'clients' => $clients
    ];
}

返回的JSON结构会自动包含每个客户端的users数组,完全匹配需求格式。

方法二:使用Query Builder实现

如果不想依赖ActiveRecord,也可以用Query Builder手动构建查询并组装数据:

基础版(存在N+1查询问题,小数据量可用)

// controllers/Api/ClientController.php
public function actionIndex()
{
    $db = Yii::$app->db;
    
    // 查询所有客户端基础数据
    $clients = $db->createCommand('SELECT id, name FROM client')->queryAll();
    
    // 遍历客户端,查询对应用户数据并组装
    foreach ($clients as &$client) {
        $client['users'] = $db->createCommand(
            'SELECT id, name, clients_id FROM user WHERE clients_id = :clientId',
            [':clientId' => $client['id']]
        )->queryAll();
    }
    
    // 返回JSON响应
    Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    return [
        'clients' => $clients
    ];
}

优化版(解决N+1查询问题)

// controllers/Api/ClientController.php
public function actionIndex()
{
    $db = Yii::$app->db;
    
    // 查询所有客户端
    $clients = $db->createCommand('SELECT id, name FROM client')->queryAll();
    $clientIds = array_column($clients, 'id');
    
    // 一次性查询所有关联用户,按clients_id分组
    $users = $db->createCommand(
        'SELECT id, name, clients_id FROM user WHERE clients_id IN (:clientIds)',
        [':clientIds' => $clientIds]
    )->queryAll();
    
    // 将用户数据按客户端ID分组映射
    $userMap = [];
    foreach ($users as $user) {
        $userMap[$user['clients_id']][] = $user;
    }
    
    // 组装客户端数据
    foreach ($clients as &$client) {
        $client['users'] = $userMap[$client['id']] ?? [];
    }
    
    // 返回JSON响应
    Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    return [
        'clients' => $clients
    ];
}

关于是否需要MySQL语法

不需要直接编写复杂的原生MySQL嵌套查询,Yii2的ActiveRecord关联或优化后的Query Builder完全可以满足需求。直接写原生SQL虽然可行,但会失去框架提供的ORM优势(如自动表前缀、查询安全、可维护性等),除非有特殊复杂场景,否则不推荐。


内容的提问来源于stack exchange,提问作者Darshan Soni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:25:56