Laravel Eloquent Eager Loading最佳实践:一对多报表关联查询疑问
Laravel 关联预加载问题解答
核心问题1:嵌套预加载是否需要重复指定父级关联
Laravel 框架的嵌套预加载机制已经做了自动处理:
- 你在
with中声明report.report_type时,框架会自动完成report和report.report_type两层关联的预加载,不需要额外把report单独加入预加载列表 - 你现有代码中的
report属于冗余声明,保留也不会报错,Laravel会自动去重已预加载的关联,不会产生多余的SQL查询
核心问题2:当前场景的最佳实践
分两种业务场景选择实现方式:
场景1:以report_type为维度展示,每个分类下挂载对应report
直接从ReportType模型出发查询,性能最优,仅产生2次SQL查询:
// 一次查所有report_type,一次查所有关联的report $reportTypes = ReportType::with('reports')->get();
场景2:你当前的业务,查询Report_history同时获取关联的report和report_type
可以简化预加载声明,去掉冗余的report参数即可:
$report_histories = Report_history::where('report_id', $report->id) ->with(['employee', 'report.report_type']) ->get();
额外优化建议
- 如果只需要report_type的部分字段,可以指定查询字段减少数据传输,注意必须带上关联的主键字段:
// 仅查询report_type的id和name字段 with(['employee', 'report.report_type:id,name']) - 如果需要给report关联加查询条件,需要显式声明report关联并传入闭包:
$report_histories = Report_history::where('report_id', $report->id) ->with([ 'employee', 'report' => function ($query) { $query->where('status', 1); // 自定义过滤条件 }, 'report.report_type' ]) ->get();
内容的提问来源于stack exchange,提问作者Mike Setyawan Mulyono
相关产品推荐
相关产品推荐

