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

如何用Query Builder实现类似Eloquent预加载的结构?

解决方案

方法一:利用Eloquent关联与预加载(推荐)

首先在Table1模型中定义与Table2、Table3的关联关系:

// app/Models/Table1.php
class Table1 extends Model
{
    // 关联Table2,一个Table1对应多条Table2记录
    public function table2Data()
    {
        return $this->hasMany(Table2::class, 'table_1_id');
    }

    // 关联Table3,一个Table1对应多条Table3记录
    public function table3Data()
    {
        return $this->hasMany(Table3::class, 'table_1_id');
    }
}

查询时直接使用with()方法预加载关联数据,Laravel会自动执行3次高效查询(一次查主表,两次批量查关联表),避免N+1性能问题,同时自动将关联数据附加到每个模型实例:

// 获取带关联数据的Table1记录
$table1Records = Table1::where(...)->where(...)->with(['table2Data', 'table3Data'])->get();

接着将结果转换为你需要的数组结构:

$result = $table1Records->keyBy('id')->map(function ($item) {
    return [
        'table2_data' => $item->table2Data->toArray(),
        'table3_data' => $item->table3Data->toArray(),
    ];
})->toArray();

最终$result的结构完全符合需求:以Table1的id为键,每个值包含对应关联的Table2、Table3数据数组。

方法二:手动用whereIn查询并组装结构(适合不想定义模型关联的场景)

如果已经先查询了Table1的数据,可手动批量查询关联表并组装结构:

  1. 提取已查询Table1的所有id:
$table1Ids = $table1Records->pluck('id')->toArray();
  1. 批量查询Table2、Table3的数据,并按table_1_id分组:
$table2Groups = Table2::whereIn('table_1_id', $table1Ids)->get()->groupBy('table_1_id')->toArray();
$table3Groups = Table3::whereIn('table_1_id', $table1Ids)->get()->groupBy('table_1_id')->toArray();
  1. 遍历Table1记录,组装目标结构:
$result = [];
foreach ($table1Records as $record) {
    $result[$record->id] = [
        'table2_data' => $table2Groups[$record->id] ?? [],
        'table3_data' => $table3Groups[$record->id] ?? [],
    ];
}

这种方式也能得到目标结构,但相比Eloquent预加载,代码更繁琐,需自行处理分组和空值情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 21:30:53