
在laravel开发中,尽管原生sql查询提供了最大的灵活性,但它往往缺乏框架提供的便利性,尤其是在处理数据分页、参数绑定和代码可读性方面。将原生sql转换为laravel的查询构建器,能够带来以下显著优势:
对于需要处理大量数据且需要分页的复杂查询,转换到查询构建器是提升开发效率和应用性能的关键一步。
面对包含子查询、聚合函数和条件逻辑的复杂原生SQL,Laravel查询构建器提供了DB::raw()和joinSub()两个强大工具来应对。
我们以一个具体的复杂查询为例,演示如何将其转换为Laravel查询构建器。原始查询涉及两个表cp_counsel和cp_cases_counsel,包含子查询、多个聚合函数、条件聚合以及分组操作,并最终需要分页。
原始SQL逻辑分析:
转换为Laravel查询构建器:
<?php
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request; // 假设 $request 对象可用
// 假设 $request->search_term 已经定义
/**
* 步骤1:构建子查询 (cpCounsel)
* 对应 SQL:
* SELECT A.enrolment_number AS id, MIN(A.counsel) AS counsel
* FROM cp_counsel AS A
* GROUP BY enrolment_number
*/
$cpCounsel = DB::table('cp_counsel as A')
->select([
'A.enrolment_number as id',
DB::raw('MIN(A.counsel) as counsel'), // 使用 DB::raw() 处理 MIN 函数
])
->groupBy('enrolment_number');
/**
* 步骤2:构建主查询 (counsels)
* 对应 SQL:
* SELECT T.counsel_id, A.counsel, COUNT(T.counsel_id) AS total,
* SUM(IF(T.court_id = 2, 1, 0)) AS supreme_court_cases,
* ... (其他条件聚合)
* FROM cp_cases_counsel AS T
* JOIN ({子查询}) AS A ON A.id = T.counsel_id
* WHERE A.counsel LIKE '%search_term%'
* GROUP BY T.counsel_id, A.counsel
*/
$counsels = DB::table('cp_cases_counsel as T')
// 使用 joinSub() 将子查询作为虚拟表 A 连接
->joinSub($cpCounsel, 'A', function ($join) {
$join->on('A.id', '=', 'T.counsel_id');
})
// 添加 where 条件
->where('A.counsel', 'like', "%{$request->search_term}%")
->select([
'T.counsel_id',
'A.counsel',
DB::raw('COUNT(T.counsel_id) as total'), // 总数聚合
// 最高法院案件数及其角色区分的条件聚合
DB::raw('SUM(if(T.court_id = 2, 1, 0)) as supreme_court_cases'),
DB::raw('SUM(if(T.court_id = 2, 1, 0) AND if(T.counsel_role = 1, 1, 0)) as supreme_court_cases_as_lead'),
DB::raw('SUM(if(T.court_id = 2, 1, 0) AND if(T.counsel_role = 2, 1, 0)) as supreme_court_cases_as_supporting'),
// 上诉法院案件数及其角色区分的条件聚合
DB::raw('SUM(if(T.court_id = 1, 1, 0)) as appeal_court_cases'),
DB::raw('SUM(if(T.court_id = 1, 1, 0) AND if(T.counsel_role = 1, 1, 0)) as appeal_court_cases_as_lead'),
DB::raw('SUM(if(T.court_id = 1, 1, 0) AND if(T.counsel_role = 2, 1, 0)) as appeal_court_cases_as_supporting'),
])
// 分组
->groupBy('T.counsel_id', 'A.counsel')
// 实现分页
->paginate(15);
// $counsels 现在是一个 Illuminate\Pagination\LengthAwarePaginator 实例
// 你可以直接在视图中使用它来渲染分页链接和数据// 查看生成的 SQL 语句 dd($counsels->toSql()); // 查看绑定参数 dd($counsels->getBindings());
通过本教程,我们了解了如何将复杂原生SQL查询转换为Laravel查询构建器。核心在于灵活运用DB::raw()来嵌入原生SQL片段,以及使用joinSub()来处理子查询。这种转换不仅提升了代码的清晰度、可维护性和安全性,更重要的是,它使得Laravel强大的分页功能能够无缝地应用于这些复杂的查询结果,从而有效管理和展示大量数据。掌握这些技巧,将极大地提高你在Laravel中处理数据库操作的能力。
以上就是如何在Laravel中将复杂原生SQL查询转换为查询构建器并实现分页的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号