laravel通用联合查询代码封装demo

 作者:Blue

 上传时间:2017-12-17

 标签: Laravel php api开发

通过i5repository的使用,觉得这个扩展包还是有很多使用不到的地方,自己用的最多的就是提供的仓库模式的使用与今天的这个demo的主角联合查询条件的自动组装,并构建好model放入控制器中使用。
下面就来谈谈自己的理解,先说说启发,laravel自带的where查询有这样的写法,

where(function($query){})

也是实现这个demo的重要东西他会将查询的条件将model对象重新构建,然后下面的使用这个构建的model对象去进行分页啊,获取条件过滤下的所有数据。但是每次都在使用时候写一遍,我是一个比较懒的人,不想每次都写一遍,所以就想着能不能将它抽离出来。答案是可以的。我这里只是一种解决方案,不一定是最好的,你觉得不好也可以按照自己的方式来。
首先,将具体实现写到自己创建的CriteriaTrait中,具体实现如下:

<?php
namespace BugsLife\Criteria;
trait Criteria
{
    /**
     * support(=,like, between, >, <, >=, <=, between,not between,in,not in)
     * @param $request
     * @return mixed
     */
    public function pushCriteria($request){
        $model = $this;
        $isFirstField = true;
        $fieldSearchable = $model->fieldSearchable;
        $model = $model->where(function ($query) use ($request, $fieldSearchable, $isFirstField){
            foreach ($fieldSearchable as $field => $condition){
                if (!is_null($request[$field])){
                    $value = $request[$field];
                    if ((strcasecmp($condition[0], '=') !== 0 && strcasecmp($condition[0], 'like') !== 0) && !is_array($value)){
                        throw new \Exception(__METHOD__.':'.'use [ '.$condition[0].' ] select field. So [ '.$field.' ] must be array()');
                    }
                    if (strcasecmp($condition[0], 'like') === 0){
                        $value = '%'. $request[$field] .'%';
                    }
                    if (strcasecmp($condition[1], 'and') === 0){
                        if($isFirstField || strcasecmp($condition[0], '=') === 0 || strcasecmp($condition[0], 'like') === 0){
                            $query->where($field, $condition[0], $value);
                            $isFirstField = false;
                        }else if (strcasecmp($condition[0], 'between') === 0){
                            $query->whereBetween($field, $value);
                        }else if (strcasecmp($condition[0], 'notBetween') === 0){
                            $query->whereNotBetween($field, $value);
                        }else if (strcasecmp($condition[0], 'in') === 0){
                            $query->whereIn($field, $value);
                        }else if (strcasecmp($condition[0], 'notIn') === 0){
                            $query->whereNotIn($field, [$value]);
                        }
                    }else{
                        if(strcasecmp($condition[0], '=') === 0 || strcasecmp($condition[0], 'like') === 0){
                            $query->orWhere($field, $condition[0], $value);
                        }else if (strcasecmp($condition[0], 'between') === 0){
                            $query->orWhereBetween($field, $value);
                        }else if (strcasecmp($condition[0], 'notBetween') === 0){
                            $query->orWhereNotBetween($field, $value);
                        }else if (strcasecmp($condition[0], 'in') === 0){
                            $query->orWhereIn($field, [$value]);
                        }else if (strcasecmp($condition[0], 'notIn') === 0){
                            $query->orWhereNotIn($field, [$value]);
                        }
                    }
                }
            }
        });
        return $model;
    }
}

然后将这个trait应用到你需要应用的model中。注意其中的除了引用外,还需要配置你的查询条件,也就是$fieldSearchable。友情提示,至于每个字段的排序方式有讲究哦,可以参考Mysql联合索引哦,遵循下左前缀哦,不然你的索引用不上哦。

<?php

namespace App\Models;

use App\Libraries\Traits\CriteriaTrait;
use Illuminate\Database\Eloquent\Model;

class AdminMenu extends Model
{
    use CriteriaTrait;

    protected $fillable = ['id', 'parent_id', 'name', 'intro', 'api_router', 'vue_router', 'state', 'sort', 'ico'];

    public $fieldSearchable = [
        'name' => ['=', 'and'],
        'intro' => ['like', 'and']
    ];

}

然后就是在控制器中使用了。

public function index()
    {
      $this->service->repository->pushCriteria(\request())->orderBy('sort', 'asc')->paginate(10)
    }

注:$this->service->repository这个其实是你的model对象。别误会有什么特殊处理,我只是分层了而已。
最新版本请移步:https://github.com/757470062/criteria/tree/dev
或者composer 安装:

composer require bugslife/criteria:dev-dev

欢迎支付宝打赏


   常用下载
  • wkhtmltox 一款将html转换成pdf的软件,laravel有相关支持包  
  • linux一键环境OneinStack(支持lnmp,lamp)