如何将Laravel Query Builder代码转换为Eloquent实现?
将Laravel Query Builder代码转换为Eloquent实现
方法一:利用Eloquent关联预加载(推荐)
这种方式贴合Laravel Eloquent的关联设计,避免手动编写JOIN语句,同时通过预加载解决N+1查询问题:
use App\Models\PatrolTransaction; use Carbon\Carbon; use Illuminate\Support\Facades\Auth; $regu = PatrolTransaction::query() // 筛选当前用户所属的client_location ->where('client_location_id', Auth::user()->client_location_id) // 限定本周的记录范围 ->whereBetween('created_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()]) // 预加载关联的PatrolUser,避免N+1查询 ->with('patrolUser') // 选择分组字段并统计总数 ->select('patrol_user_id', DB::raw('count(*) as total')) // 按巡逻用户ID分组 ->groupBy('patrol_user_id') ->get() // 映射结果,补充关联的用户名 ->map(function ($transactionGroup) { return (object)[ 'patrol_user_id' => $transactionGroup->patrol_user_id, 'total' => $transactionGroup->total, 'name' => $transactionGroup->patrolUser?->name // 空安全访问,兼容关联不存在的场景 ]; });
方法二:保留JOIN逻辑的Eloquent写法
如果希望和原Query Builder的逻辑完全对齐,可以直接在Eloquent查询中使用JOIN:
use App\Models\PatrolTransaction; use Carbon\Carbon; use Illuminate\Support\Facades\Auth; $regu = PatrolTransaction::query() ->leftJoin('patrol_users', 'patrol_transactions.patrol_user_id', '=', 'patrol_users.id') ->where('patrol_transactions.client_location_id', Auth::user()->client_location_id) ->whereBetween('patrol_transactions.created_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()]) ->select( 'patrol_transactions.patrol_user_id', DB::raw('count(*) as total'), 'patrol_users.name as name' ) ->groupBy('patrol_transactions.patrol_user_id', 'patrol_users.name') ->get();
注意事项
- 模型命名修正:你提供的模型文件名为
PatrolTansaction.php(拼写缺失s),实际需改为PatrolTransaction.php,否则Eloquent无法正确映射数据表。 - 空值防护:确保
Auth::user()返回有效用户对象,且包含client_location_id字段,避免空指针错误。 - 时区适配:
Carbon::now()默认使用应用配置时区,若需按特定时区统计,可改为Carbon::now('Asia/Shanghai')这类指定时区的写法。
内容的提问来源于stack exchange,提问作者stackover flow
相关产品推荐
相关产品推荐

