thinkphp数据库查询构造器如何拼接复杂条件

thinkphp数据库查询构造器如何拼接复杂条件
最新回答
天暗下来你就是光

2020-09-24 07:24:00

ThinkPHP的数据库查询构造器通过链式调用和多种条件组合方式,能够灵活拼接复杂查询条件,尤其适用于动态生成SQL的场景。以下是具体实现方法及示例:

1. 使用where方法组合基本条件

where()支持字符串、数组、闭包等多种格式,默认多个where条件为AND关系:

// 字符串格式$query->where('name', 'like', '%think%');// 数组格式(等值查询)$query->where(['status' => 1, 'type' => 2]);// 链式调用(AND关系)$query->where('status', 1)->where('score', '>', 80);

生成SQL:WHERE status = 1 AND score > 80

2. 使用闭包实现嵌套条件(括号分组)

闭包用于包裹子条件,自动添加括号形成独立逻辑块,解决类似(a=1 OR b=2) AND c=3的嵌套需求:

$query->where(function ($q) { $q->where('a', 1)->whereOr('b', 2); // (a=1 OR b=2)})->where('c', 3); // AND c=3

生成SQL:WHERE (a = 1 OR b = 2) AND c = 3

3. 混合使用where与whereOr控制优先级

链式调用中混用where和whereOr时,需注意AND/OR的优先级。若逻辑不明确,建议用闭包分组:

// 示例1:优先级问题(可能不符合预期)$query->where('status', 1) ->whereOr('score', '>', 90) ->where('deleted', 0);// 生成SQL:WHERE status = 1 OR score > 90 AND deleted = 0// 示例2:明确分组(推荐)$query->where(function ($q) { $q->where('status', 1)->whereOr('score', '>', 90);})->where('deleted', 0);// 生成SQL:WHERE (status = 1 OR score > 90) AND deleted = 04. 使用数组定义复合条件

通过数组一次性定义复杂结构,适合配置化或动态构建查询:

$map = [ 'status' => 1, 'type' => ['in', [1, 2, 3]], function ($query) { $query->where('level', '>=', 5)->whereOr('vip', 1); }];$result = Db::name('user')->where($map)->select();

生成SQL:WHERE status = 1 AND type IN (1, 2, 3) AND (level >= 5 OR vip = 1)

5. 结合exp表达式实现高级操作

对于原生表达式或特殊函数,可用exp配合Db::raw()插入原始SQL片段(需注意SQL注入风险):

// 使用exp表达式$query->where('create_time', 'exp', Db::raw('BETWEEN 1609430400 AND 1609516800'));// 直接使用Db::raw()$query->whereExp('name', "LIKE '%test%' OR name LIKE '%demo%'");

生成SQL:WHERE create_time BETWEEN 1609430400 AND 1609516800或WHERE name LIKE '%test%' OR name LIKE '%demo%'

关键技巧总结
  • 闭包分组:通过闭包包裹子条件,自动添加括号,是处理复杂逻辑的核心。
  • 链式调用顺序:where与whereOr的混合使用需注意优先级,不明确时优先用闭包。
  • 数组结构:适合动态构建查询条件,闭包在数组中同样会被解析为括号分组。
  • 安全性:使用Db::raw()插入原生SQL时,需防范SQL注入,建议对参数进行过滤或转义。

通过合理组合上述方法,可以清晰、安全地构建多层嵌套的复杂查询条件。