如何在Laravel Eloquent中关联3张以上的数据表?
解决Laravel Eloquent四张表关联问题
嘿,我来帮你搞定这个四张表的关联查询问题~结合你之前用Query Builder关联三张表的经验,这里给你两种实现方式,一种是延续你熟悉的Query Builder写法,另一种是更贴合Eloquent ORM风格的模型关联写法。
方法一:使用Query Builder(快速衔接你的现有代码)
你之前已经会用DB::table()结合join关联三张表,现在只需要在原有基础上新增A表的关联逻辑,对应你给出的SQL条件即可:
$queries = DB::table('A') ->join('B', 'B.id', '=', 'A.B_id') // 关联A和B:A的B_id对应B的id ->join('D', 'D.B_id', '=', 'B.id') // 关联B和D:D的B_id对应B的id ->join('E', 'E.id', '=', 'D.E_id') // 关联D和E:D的E_id对应E的id ->select('*') ->get();
这个写法完全对应你给出的SQL逻辑,只是把原生SQL的关联条件转换成了join方法的参数,逻辑和你之前关联B、D、E三张表的思路完全一致,只是多了一步A表的关联。
方法二:使用Eloquent模型关联(更符合Laravel ORM设计,推荐)
如果想充分利用Eloquent的特性,比如预加载避免N+1查询、代码可读性更高,建议先给四张表创建对应的模型,然后定义它们之间的关联关系:
第一步:创建模型并定义关联
假设你的模型都放在App\Models目录下:
- A模型(App\Models\A):A表有
B_id外键,属于B表
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class A extends Model { protected $table = 'A'; // 如果模型名和表名一致可以省略,这里假设表名是A public function b(): BelongsTo { return $this->belongsTo(B::class); } }
- B模型(App\Models\B):B表被A表关联(一对多),同时关联D表(一对多)
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; class B extends Model { protected $table = 'B'; public function a(): HasMany { return $this->hasMany(A::class); } public function d(): HasMany { return $this->hasMany(D::class); } }
- D模型(App\Models\D):D表有
B_id和E_id外键,分别属于B表和E表
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class D extends Model { protected $table = 'D'; public function b(): BelongsTo { return $this->belongsTo(B::class); } public function e(): BelongsTo { return $this->belongsTo(E::class); } }
- E模型(App\Models\E):E表被D表关联(一对多)
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; class E extends Model { protected $table = 'E'; public function d(): HasMany { return $this->hasMany(D::class); } }
第二步:查询关联数据
定义好关联后,就可以用Eloquent的with方法预加载所有关联数据,比如从A表出发获取对应的B、D、E数据:
// 获取所有A记录,以及关联的B、B关联的D、D关联的E $aRecords = \App\Models\A::with('b.d.e')->get(); // 遍历数据示例 foreach ($aRecords as $a) { echo "A的ID:{$a->id}"; echo "关联的B名称:{$a->b->name}"; // 假设B表有name字段 foreach ($a->b->d as $d) { echo "关联的D记录:{$d->id},对应的E名称:{$d->e->name}"; } }
如果需要像原生SQL那样获取所有字段的平级结果,也可以结合模型和join写法:
$results = \App\Models\A::join('B', 'B.id', '=', 'A.B_id') ->join('D', 'D.B_id', '=', 'B.id') ->join('E', 'E.id', '=', 'D.E_id') ->select('A.*', 'B.*', 'D.*', 'E.*') ->get();
两种方式的选择
- 如果你只是需要快速实现查询,Query Builder写法更直接,和你之前的代码风格一致;
- 如果你希望代码更优雅、易于维护,并且需要避免N+1查询问题,Eloquent模型关联是更好的选择。
内容的提问来源于stack exchange,提问作者Yavuz
相关产品推荐
相关产品推荐

