Laravel中如何将DB查询转换为Eloquent关联关系?
重构为Eloquent关联及查询优化方案
首先先修正你原查询里的一个明显问题:rightjoin(table3, table1.id, '=', table3.id) 这里的关联条件应该是 table1.id = table3.table1_id,因为你的table3表外键是table1_id,否则这个关联逻辑不成立,先把这个点纠正。
一、重构为Eloquent关联关系
1. 创建对应模型
先给三个表创建Eloquent模型(默认放在app/Models目录下):
Table1.php
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; class Table1 extends Model { protected $table = 'table1'; // 关联Table2 public function table2s(): HasMany { return $this->hasMany(Table2::class, 'table1_id', 'id'); } // 关联Table3 public function table3s(): HasMany { return $this->hasMany(Table3::class, 'table1_id', 'id'); } }
Table2.php
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class Table2 extends Model { protected $table = 'table2'; public function table1(): BelongsTo { return $this->belongsTo(Table1::class, 'table1_id', 'id'); } }
Table3.php
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class Table3 extends Model { protected $table = 'table3'; public function table1(): BelongsTo { return $this->belongsTo(Table1::class, 'table1_id', 'id'); } }
2. 用Eloquent实现原查询逻辑
如果要保持原查询的left join + right join返回结构(合并字段的集合),可以用Eloquent模型来写join:
use App\Models\Table1; public function something() { $something_var = Table1::leftJoin('table2', 'table1.id', '=', 'table2.table1_id') ->rightJoin('table3', 'table1.id', '=', 'table3.table1_id') ->select('table1.*', 'table2.column as table2_column', 'table3.column as table3_column') ->paginate(10); }
如果希望返回Table1模型并携带关联的table2和table3数据(而非合并字段),可以用预加载(适合需要操作模型实例的场景):
use App\Models\Table3; public function something() { // 对应原right join table3的逻辑,先查Table3再关联关联数据 $something_var = Table3::with(['table1', 'table1.table2s']) ->select('table3.*', 'table1.id as table1_id', 'table1.column as table1_column') ->paginate(10); }
二、查询优化方案
- 明确指定查询字段:永远不要用默认的
select *,只查询你需要用到的字段,减少数据传输和内存占用。 - 添加索引:给
table2.table1_id和table3.table1_id添加外键索引,大幅提升join查询效率,执行以下SQL:ALTER TABLE table2 ADD INDEX idx_table2_table1_id (table1_id); ALTER TABLE table3 ADD INDEX idx_table3_table1_id (table1_id); - 梳理join逻辑:原查询的
left join + right join组合可能导致结果集不符合预期,建议先明确业务需求:如果是要保留所有table3的数据并关联对应table1、table2,用Table3::with()的方式更符合Eloquent设计思想。 - 分页优化:如果数据量极大,可改用
cursorPaginate()替代paginate(),避免查询总条数的开销,适合大数据量分页场景。
内容的提问来源于stack exchange,提问作者Phoenix
相关产品推荐
相关产品推荐

