丰富 Eloquent ORM 的 where 查询条件的解析场景
Posted big_cat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了丰富 Eloquent ORM 的 where 查询条件的解析场景相关的知识,希望对你有一定的参考价值。
个人感觉 Eloquent ORM
的 where
条件解析场景并不是那么的丰富,很多条件的拼装都需要引入额外的 orWhere, whereNotIn, whereBetween, whereNotBetween
来辅助完成。这样在做一些抽象的底层查询方法时,不是很友好,上层传递的查询条件是不确定的,如果能灵活的解析各种混合式的查询条件(用数组的方式描述),使用起来会更高效灵活些。
/**
* 渲染复杂的 where 查询条件
* @param Builder $query
* @param $conditions
*/
public static function renderWhereMixedEloquent(Builder $query, $conditions)
{
$lastEl = end($conditions);
reset($conditions);
if (is_string($lastEl) && ((\'or\' == $lastEl || \'and\' == $lastEl))) {
$logic = $lastEl;
array_pop($conditions);
} else {
$logic = \'and\';
}
$conditionsKeys = array_keys($conditions);
$conditionsKeyFirst = $conditionsKeys[0];
if (is_numeric($conditionsKeyFirst)) {
if (is_array($conditions[$conditionsKeyFirst])) {
if (\'or\' == $logic) {
$query->where(function (Builder $query) use ($conditions) {
foreach ($conditions as $conditionsSub) {
$query->orWhere(function (Builder $query) use ($conditionsSub) {
static::renderWhereMixedEloquent($query, $conditionsSub);
});
}
});
} else {
$query->where(function (Builder $query) use ($conditions) {
foreach ($conditions as $conditionsSub) {
$query->where(function (Builder $query) use ($conditionsSub) {
static::renderWhereMixedEloquent($query, $conditionsSub);
});
}
});
}
} else {
$operator = $conditions[1];
switch ($operator) {
case \'in\':
$query->whereIn($conditions[0], $conditions[2], $logic);
break;
case \'between\':
$query->whereBetween($conditions[0], $conditions[2], $logic);
break;
case \'not in\':
$query->whereIn($conditions[0], $conditions[2], $logic, true);
break;
case \'not between\':
$query->whereBetween($conditions[0], $conditions[2], $logic, true);
break;
default:
$query->where(...$conditions);
}
}
} else {
$query->where(function (Builder $query) use ($logic, $conditions) {
if (\'and\' == $logic) {
foreach ($conditions as $col => $val) {
$query->where([$col => $val]);
}
} else {
foreach ($conditions as $col => $val) {
$query->orWhere([$col => $val]);
}
}
});
}
}
使用示例
简单的and条件
$conditions = [
\'name\' => \'lily\',
\'sex\' => \'f\',
];
$conditions = [
\'name\' => \'lily\',
\'sex\' => [\'f\', \'m\'],
];
简单的or条件
$conditions = [
\'name\' => \'lily\',
\'sex\' => [\'f\', \'m\'],
\'or\'
];
复杂的and/or查询
$conditions = [
[
[\'id\', \'>\', 5],
[\'hobby\', \'in\', [\'football\', \'swimming\']],
[\'created_at\', \'between\', [strtotime(\'2020-05-20 10:38:41\'), strtotime(\'2021-05-25 10:39:41\')]],
],
[
[\'id\', \'>\', 5],
[\'hobby\', \'in\', [\'football\', \'swimming\']],
[\'created_at\', \'between\', [strtotime(\'2020-05-20 10:38:41\'), strtotime(\'2021-05-25 10:39:41\')]],
],
];//组1 and 组2
$conditions = [
[
[\'id\', \'=\', 5],
[\'hobby\', \'in\', [\'football\', \'swimming\']],
[\'created_at\', \'between\', [strtotime(\'2020-05-20 10:38:41\'), strtotime(\'2021-05-25 10:39:41\')]],
\'or\'//组1的内部做 or
],
[
[\'id\', \'>\', 5],
[\'hobby\', \'not in\', [\'football\', \'swimming\']],
[\'created_at\', \'not between\', [strtotime(\'2020-05-20 10:38:41\'), strtotime(\'2021-05-25 10:39:41\')]],
],
\'or\',//组1 or 组2
];
$conditions = [
\'sex\' => [\'f\', \'m\'],//没问题,只要表达式的语义正确,只要你头不晕,就能混拼,
[\'name\', \'=\', \'test\'],
[
[\'id\', \'>\', 5],
[\'hobby\', \'in\', [\'football\', \'swimming\']],
[\'created_at\', \'between\', [strtotime(\'2020-05-20 10:38:41\'), strtotime(\'2021-05-25 10:39:41\')]],
\'or\'//组1的内部做 or
],
[
[\'id\', \'>\', 5],
[\'hobby\', \'in\', [\'football\', \'swimming\']],
[\'created_at\', \'between\', [strtotime(\'2020-05-20 10:38:41\'), strtotime(\'2021-05-25 10:39:41\')]],
],
\'or\',//组1 or 组2
];
使用实例
// < 8.0
$query = User::select("*");//主要是拿到 Builder 对象
// $query 是对象 引用传值
User::renderWhereMixedEloquent($query, $conditions);
$query->get();
// 8.0
$query = User::query();
// $query 是对象 引用传值
User::renderWhereMixedEloquent($query, $conditions);
$query->get();
以上是关于丰富 Eloquent ORM 的 where 查询条件的解析场景的主要内容,如果未能解决你的问题,请参考以下文章
Laravel Eloquent ORM 中的 join()->where()