通过i5repository的使用,觉得这个扩展包还是有很多使用不到的地方,自己用的最多的就是提供的仓库模式的使用与今天的这个demo的主角联合查询条件的自动组装,并构建好model放入控制器中使用。
下面就来谈谈自己的理解,先说说启发,laravel自带的where查询有这样的写法,
where(function($query){})
也是实现这个demo的重要东西他会将查询的条件将model对象重新构建,然后下面的使用这个构建的model对象去进行分页啊,获取条件过滤下的所有数据。但是每次都在使用时候写一遍,我是一个比较懒的人,不想每次都写一遍,所以就想着能不能将它抽离出来。答案是可以的。我这里只是一种解决方案,不一定是最好的,你觉得不好也可以按照自己的方式来。
首先,将具体实现写到自己创建的CriteriaTrait中,具体实现如下:
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联合索引哦,遵循下左前缀哦,不然你的索引用不上哦。
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
欢迎支付宝打赏