laravel 中关于模型查询构造器的特殊用法

laravel 中关于模型查询构造器的特殊用法


记录一些相对比较常用的特殊用例。

1、whereHas

有时在模型关联中会碰到需要跨模型判断条件来获取数据的情况,比如存在两张表 usersroles ,需要获取角色为 viki 的用户。
在模型关联时,官方已经提供了方法 whereHas,实际上最好还是去查看一下 laravel源码 会更容易理解,助手函数示例如下:

	/**
             * Add a relationship count / exists condition to the query with where clauses.
             *
             * @param string $relation
             * @param \Closure|null $callback
             * @param string $operator
             * @param int $count
             * @return \Illuminate\Database\Eloquent\Builder|static 
             * @static 
             */ 
            public static function whereHas($relation, $callback = null, $operator = '>=', $count = 1)
            {
                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
                                return $instance->whereHas($relation, $callback, $operator, $count);
            }

此处该查询语句可以这样写:

User::whereHas('role', function($query) {
	// 此处闭包可以追加你需要的任何laravel支持的查询结果语句
    $query->where('name', 'viki');
})->get();

当然,肯定也是存在 orWhereHas 该方法的。

2、when

在做查询语句时,经常会碰到需要判断上一个条件是否为真则执行语句的问题。这种情况下很容易拆成两段 sql 语句查询,实际上用 when 即可解决,给出 _ide_helper 的代码追踪:

   /**
             * Apply the callback's query changes if the given "value" is true.
             *
             * @param mixed $value
             * @param callable $callback
             * @param callable|null $default
             * @return mixed|$this 
             * @static 
             */ 
            public static function when($value, $callback, $default = null)
            {
                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
                                return $instance->when($value, $callback, $default);
            }

实际上的使用参考如下:

/**
     * 获取原todo-list事项
     *
     * @param $userIds
     * @param $supervisorUserIDs
     * @return mixed
     */
    public function gainTodoList($userIds, $supervisorUserIDs)
    {
        return $this->todoSummaryRepository
            ->orderByDesc('created_at')
            ->where('status', 1)
            ->where('type', 1)
            ->when(Admin::user()->isAdministrator(), function ($query) use ($supervisorUserIDs) {
                $supervisorUserIDs = array_merge([Admin::user()->id], $supervisorUserIDs);
                $query->whereIn('executor_id', $supervisorUserIDs);// 包含其他主管被指定任务
            })
            ->when(!Admin::user()->isAdministrator(), function ($query) use ($userIds) {
                $query->when($userIds, function ($query) use ($userIds) {
                    $userIds = array_merge([Admin::user()->id], $userIds);
                    $query->whereIn('executor_id', $userIds);// 包含其他成员被指定任务
                })
                    ->when(!$userIds, function ($query) {
                        $query->where('executor_id', Admin::user()->id);// 自身任务
                    });
            })
            ->get();
    }

不难看出,when 会判断第一个参数的真与假,如果是真,则执行第一个 callback,如果是假,则执行默认的方法,代码就只设置了真的时候需要执行的代码,因为条件有三种,不只有两种。这样的话可以使代码易读性更好,当然也可以拆分子句,但是 when 这个用法相对更赞。

很显然,该方法中的最后一个 when 的超管不存在的条件判断,只要放入到上一个 when 方法的最后一个闭包函数内即可:

 /**
     * 获取原todo-list事项
     *
     * @param $userIds
     * @param $supervisorUserIDs
     * @return mixed
     */
    public function gainTodoList($userIds, $supervisorUserIDs)
    {
        return $this->todoSummaryRepository
            ->orderByDesc('created_at')
            ->where('status', 1)
            ->where('type', 1)
            ->when(
                Admin::user()->isAdministrator(),
                function ($query) use ($supervisorUserIDs) {
                    $supervisorUserIDs = array_merge([Admin::user()->id], $supervisorUserIDs);
                    $query->whereIn('executor_id', $supervisorUserIDs);// 包含其他主管被指定任务
                },
                function ($query) use ($userIds) {
                    $query->when($userIds, function ($query) use ($userIds) {
                        $userIds = array_merge([Admin::user()->id], $userIds);
                        $query->whereIn('executor_id', $userIds);// 包含其他成员被指定任务
                    })
                        ->when(!$userIds, function ($query) {
                            $query->where('executor_id', Admin::user()->id);// 自身任务
                        });
                })
            ->get();
    }

todo 后续如有则继续补充


laravel 6 版本关于查询构造的方法文件位于该路径:

vendor/laravel/framework/src/Illuminate/Database/Eloquent

vendor/laravel/framework/src/Illuminate/Database/Query

// 模型关联的方法文件
vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值