Laravel Eloquent多表查询:如何实现会员与公司模型的指定条件关联查询
把你的SQL转换成Laravel Eloquent的实现方案
嘿,我来帮你把这段原生SQL转换成Laravel Eloquent的写法,咱们先拆解一下原查询的核心逻辑,再对应到Eloquent的语法上:
原SQL要做的是:
- 关联
members和companies两张表(隐式内连接) - 筛选
members.main_type = 2、members.status = 1且members.main_id匹配companies.id的记录 - 同时满足
members.username包含关键词,或者companies.name包含关键词
方法一:用join贴近原生SQL逻辑
这种写法和你原SQL的逻辑几乎完全一致,适合需要直接获取两张表所有字段的场景:
// 先定义搜索关键词 $keywords = '你要搜索的内容'; $results = Member::select('*') // 关联companies表,指定别名和关联条件 ->join('companies as c', 'members.main_id', '=', 'c.id') // 基础过滤条件 ->where('members.main_type', 2) ->where('members.status', 1) // 用闭包包裹OR条件,确保逻辑优先级正确(避免和前面的AND条件混淆) ->where(function ($query) use ($keywords) { $query->where('members.username', 'like', "%{$keywords}%") ->orWhere('c.name', 'like', "%{$keywords}%"); }) ->get();
方法二:使用Eloquent关联(更符合Laravel风格)
首先需要在Member模型里定义和Company的关联关系:
// app/Models/Member.php public function company() { // 因为外键是main_id(不是默认的company_id),所以需要手动指定 return $this->belongsTo(Company::class, 'main_id'); }
然后就可以用whereHas过滤关联的Company数据,同时用with预加载关联模型(避免N+1查询问题):
$keywords = '你要搜索的内容'; $results = Member::with('company') ->where('main_type', 2) ->where('status', 1) ->where(function ($query) use ($keywords) { // 过滤member自身的username字段 $query->where('username', 'like', "%{$keywords}%") // 过滤关联的company的name字段 ->orWhereHas('company', function ($subQuery) use ($keywords) { $subQuery->where('name', 'like', "%{$keywords}%"); }); }) ->get();
额外提示
- 关于SQL注入安全:如果关键词来自用户输入,建议用参数绑定的方式更稳妥,比如把
"%{$keywords}%"改成DB::raw('concat("%", ?, "%")')并绑定参数:->where('members.username', 'like', DB::raw('concat("%", ?, "%")'), [$keywords]) - 两种写法的区别:
join写法会直接返回两张表的所有字段,而关联写法会把Company数据嵌套在Member对象里,更适合后续使用模型的关联属性(比如$member->company->name)。
内容的提问来源于stack exchange,提问作者Yasin Erarslan
相关产品推荐
相关产品推荐

