Laravel 9+Inertia.js多表数据查询优化方案咨询
Laravel 9 + Inertia.js 设备列表查询优化方案
一、解决主关联(company/modele/uklad)的N+1查询问题
你已经在Device模型定义了belongsTo关联,直接用**预加载(Eager Loading)**就能替代闭包里的单独查询:
1. 确认Device模型的关联定义(确保已正确设置)
// app/Models/Device.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Device extends Model { // 关联公司 public function company() { return $this->belongsTo(Company::class); } // 关联型号 public function modele() { return $this->belongsTo(Modele::class); } // 关联系统 public function uklad() { return $this->belongsTo(Uklad::class); } // 关联设备位置中间表 public function deviceLokale() { return $this->hasMany(DeviceLokale::class); } }
2. 控制器中添加预加载
在查询Device列表时,用with()方法一次性加载所有需要的关联数据,替代循环内的单独查询:
// 控制器代码示例 use App\Models\Device; use Inertia\Inertia; public function index() { // 预加载所有关联,包括嵌套的Lokale $devices = Device::with([ 'company', 'modele', 'uklad', 'deviceLokale.lokale' // 嵌套预加载:先加载deviceLokale,再加载对应的Lokale ])->get(); // 如果是分页场景,改成paginate即可 // $devices = Device::with([...])->paginate(15); return Inertia::render('Devices/Index', [ 'devices' => $devices ]); }
二、优化DeviceLokale与Lokale的关联查询
通过嵌套预加载deviceLokale.lokale,可以一次性获取所有设备对应的位置数据,无需在前端或闭包中循环查询:
1. 确认关联模型定义
// app/Models/DeviceLokale.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class DeviceLokale extends Model { // 关联位置表 public function lokale() { return $this->belongsTo(Lokale::class); } }
2. 前端直接访问关联数据
在Inertia的Vue/React组件中,直接通过预加载后的属性访问关联数据,无需再发起额外请求:
<!-- Vue组件示例 --> <template> <div> <table> <thead> <tr> <th>设备名称</th> <th>所属公司</th> <th>型号</th> <th>系统</th> <th>所在位置</th> </tr> </thead> <tbody> <tr v-for="device in devices" :key="device.id"> <td>{{ device.name }}</td> <!-- 直接访问预加载的company关联 --> <td>{{ device.company?.name }}</td> <td>{{ device.modele?.name }}</td> <td>{{ device.uklad?.name }}</td> <!-- 遍历预加载的deviceLokale及其关联的lokale --> <td> <span v-for="dl in device.deviceLokale" :key="dl.id"> {{ dl.lokale?.name }} </span> </td> </tr> </tbody> </table> </div> </template>
关键原理说明
预加载通过with()方法将原本的N+1次数据库查询(1次查所有设备,N次查每个设备的关联)合并为1 + M次查询(M是关联表的数量),大幅减少数据库请求次数,提升页面加载速度。
内容的提问来源于stack exchange,提问作者NoAd
相关产品推荐
相关产品推荐

