Browse Source

:construction: whereIn 支持 多字段

visuddhinanda 3 years ago
parent
commit
8bc3382b04
2 changed files with 85 additions and 3 deletions
  1. 9 3
      app/Providers/AppServiceProvider.php
  2. 76 0
      app/Tools/QueryBuilderMacro.php

+ 9 - 3
app/Providers/AppServiceProvider.php

@@ -4,7 +4,10 @@ namespace App\Providers;
 
 use Godruoyi\Snowflake\Snowflake;
 use Godruoyi\Snowflake\LaravelSequenceResolver;
-
+use App\Tools\QueryBuilderMacro;
+use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
+use Illuminate\Database\Eloquent\Relations\Relation;
+use Illuminate\Database\Query\Builder as QueryBuilder;
 use Illuminate\Support\ServiceProvider;
 
 class AppServiceProvider extends ServiceProvider
@@ -17,7 +20,7 @@ class AppServiceProvider extends ServiceProvider
     public function register()
     {
         //雪花算法
-		
+
 		$this->app->singleton('snowflake', function () {
             return (new Snowflake(env('SNOWFLAKE_DATA_CENTER_ID'),env('SNOWFLAKE_WORKER_ID')))
                 ->setStartTimeStamp(strtotime(config('database.snowflake.start'))*1000)
@@ -25,7 +28,7 @@ class AppServiceProvider extends ServiceProvider
                     new LaravelSequenceResolver($this->app->get('cache')->store()
                 ));
         });
-		
+
     }
 
     /**
@@ -36,5 +39,8 @@ class AppServiceProvider extends ServiceProvider
     public function boot()
     {
         //
+        QueryBuilder::mixin($queryBuilderMacro = $this->app->make(QueryBuilderMacro::class));
+        EloquentBuilder::mixin($queryBuilderMacro);
+        Relation::mixin($queryBuilderMacro);
     }
 }

+ 76 - 0
app/Tools/QueryBuilderMacro.php

@@ -0,0 +1,76 @@
+<?php
+/**
+ * 作者:guanguans
+ * 链接:https://juejin.cn/post/7116779474783305735
+ * 来源:稀土掘金
+ * 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
+ */
+namespace App\Tools;
+
+use Illuminate\Contracts\Support\Arrayable;
+
+class QueryBuilderMacro
+{
+    public function whereIns(): callable
+    {
+        /* @var Arrayable|array[] $values */
+        return function (array $columns, $values, string $boolean = 'and', bool $not = false) {
+            /** @var \Illuminate\Database\Eloquent\Builder $this */
+            $type = $not ? 'not in' : 'in';
+
+            $rawColumns = implode(',', $columns);
+
+            $values instanceof Arrayable and $values = $values->toArray();
+            $values = array_map(function ($value) use ($columns) {
+                if (array_is_list($value)) {
+                    return $value;
+                }
+
+                return array_reduce($columns, function ($sortedValue, $column) use ($value) {
+                    $sortedValue[$column] = $value[$column] ?? trigger_error(
+                        sprintf(
+                            '%s: %s',
+                            'The value of the column is not found in the array.',
+                            $column
+                        ),
+                        E_USER_ERROR
+                    );
+
+                    return $sortedValue;
+                }, []);
+            }, $values);
+
+            $rawValue = sprintf('(%s)', implode(',', array_fill(0, count($columns), '?')));
+            $rawValues = implode(',', array_fill(0, count($values), $rawValue));
+
+            $raw = "($rawColumns) $type ($rawValues)";
+
+            return $this->whereRaw($raw, $values, $boolean);
+        };
+    }
+
+    public function whereNotIns(): callable
+    {
+        return function (array $columns, $values) {
+            /** @var \Illuminate\Database\Eloquent\Builder $this */
+            return $this->whereIns($columns, $values, 'and', true);
+        };
+    }
+
+    public function orWhereIns(): callable
+    {
+        return function (array $columns, $values) {
+            /** @var \Illuminate\Database\Eloquent\Builder $this */
+            return $this->whereIns($columns, $values, 'or');
+        };
+    }
+
+    public function orWhereNotIns(): callable
+    {
+        return function (array $columns, $values) {
+            /** @var \Illuminate\Database\Eloquent\Builder $this */
+            return $this->whereIns($columns, $values, 'or', true);
+        };
+    }
+}
+