You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中不使用join实现多表关联的替代方案咨询

不使用JOIN的Eloquent多表关联实现方案

第一步:定义模型间的关联关系

首先要在Eloquent模型中明确表之间的关联,这是替代JOIN的核心:

User 模型(app/Models/User.php)

// 一个用户对应一条理发师记录
public function barber()
{
    return $this->hasOne(Barber::class, 'id_user');
}

Barber 模型(app/Models/Barber.php)

// 理发师归属一个用户
public function user()
{
    return $this->belongsTo(User::class, 'id_user');
}

// 一个理发师对应多条评价
public function avis()
{
    return $this->hasMany(Avis::class, 'id_barber');
}

// 一个理发师对应多条订单(对应原查询中的commandes)
public function commandes()
{
    return $this->hasMany(Commande::class, 'id_barber');
}

第二步:重写查询逻辑(无JOIN版)

利用Eloquent的with(预加载关联数据)、whereHas(筛选关联满足条件的主模型)方法替代JOIN,实现相同业务逻辑:

$barbers = Barber::with('user')
    // 关联用户必须为已验证状态
    ->whereHas('user', function($query) {
        $query->where('isValidate', true);
    })
    // 筛选理发师状态为1或4
    ->whereIn('id_state', [1, 4])
    // 筛选订单数量达标理发师
    ->whereHas('commandes', function($query) use ($searchTermes1) {
        $query->groupBy('id_barber')
              ->havingRaw('count(*) >= ?', [(int)$searchTermes1]);
    })
    // 确保理发师存在对应评价记录(对应原查询的JOIN avis)
    ->whereHas('avis')
    // 搜索匹配逻辑:理发师名称 或 用户姓名组合
    ->where(function($query) use ($searchTerm) {
        $query->where('name_barber', 'like', "%{$searchTerm}%")
              ->orWhereHas('user', function($userQuery) use ($searchTerm) {
                  $userQuery->whereRaw("concat(first_name, ' ', last_name) like ?", ["%{$searchTerm}%"])
                            ->orWhereRaw("concat(last_name, ' ', first_name) like ?", ["%{$searchTerm}%"]);
              });
    })
    // 按理发师创建时间倒序排序
    ->orderBy('created_at', 'desc')
    // 分页返回结果
    ->paginate(10);

逻辑说明

  • with('user'):预加载关联用户数据,避免N+1查询问题,替代原查询中SELECT users.*的需求
  • whereHas:用于筛选主模型(Barber)存在满足条件的关联模型(User、commandes、avis),替代JOIN后的条件筛选
  • 所有条件通过关联关系传递,完全避免手动编写JOIN语句,符合Eloquent的ORM设计思想

内容的提问来源于stack exchange,提问作者Roronoa Zoro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 05:27:23