Laravel ORM中with,where, has,wherehas的使用

共同之处,这三个函数的参数,都是 model 中的 relationship function 的名字。

  • 1 对 N
  • N 对 N

with

类似于 SQL 中的 left join。左侧数据会全部显示。

with 是 eager loading,即预加载关系数据。

has

类似于 SQL 中的 inner join。

当右侧有数据时才会显示。

注意,has 跟 whereHas 并不返回关系数据。

whereHas

inner join 之后,可以补充查询条件

whereHas 实际应用场景

例如,backpack 中的 N 对 N 关系的过滤,使用 whereHas

$this->crud->addFilter([ // select2_multiple filter
  'name' => 'roles',
  'type' => 'select2_multiple',
  'label'=> '角色'
], function() { // the options that show up in the select2
	return Role::all()->pluck('name', 'id')->toArray();
}, function($values) { // if the filter is active
	foreach (json_decode($values) as $key => $value) {
		$this->crud->query = $this->crud->query->whereHas('roles', function ($query) use ($value) {
			$query->where('role_id', $value);
		});
	}
});


if(!request('roles')){
	 $this->crud->addClause('whereHas', 'roles');
}
$users = User::whereHas('posts', function($q){
    $q->where('created_at', '>=', '2015-01-01 00:00:00');
})->get();

with 的实际应用

但是 with 的条件查询,并没有启动过滤左侧连表的作用,只会使右侧连表显示为 null。 所以是典型的 left join。

例如,下面语句,还是会显示所有的发帖,而不是 is_master 的发帖。

$items = Post::with(["user" => function($q){
    $q->where('is_master', 1);
}])->where('category_id', $category_id)
    ->where('status', 1)
    ->orderBy('id', 'desc')
    ->offset($offset)
    ->limit($limit)
    ->get();

所以,这种情况下,应该使用 whereHas.

注意

  • whereHas 跟 with 的语法不一致
  • whereHas 和 has 并不返回关系数据,但是 with 是返回的。所以,当要返回关系数据时,两者要结合使用。
$items = Post::whereHas("user", function($q){
    $q->where('is_master', 1);
})->with(['user' => function($q) {
    $q->where('is_master', 1);
}])->where('status', 1)
    ->where('top', 0)
    ->orderBy('id', 'desc')
    ->offset($offset)
    ->limit($limit)
    ->get();
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值