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();
Laravel ORM,也被称为 Eloquent ORM,是 Laravel 框架中用于处理数据库操作的核心组件之一。它提供了一种直观且面向对象的方式来与数据库进行交互。以下是几个核心功能的使用教程和示例。 ### 定义模型 在 Laravel 中,每个数据库表都有一个对应的“模型”,用于与该表进行交互。模型允许您执行查询、插入、更新和删除记录等操作。 ```php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class User extends Model { use HasFactory; // 定义可批量赋值的字段 protected $fillable = ['name', 'email', 'age']; // 定义不可批量赋值的字段 protected $guarded = ['id']; } ``` ### 查询数据 使用 Eloquent ORM 可以轻松地执行各种查询操作。以下是一些常见的查询示例: #### 获取所有记录 ```php $users = User::all(); ``` #### 根据条件获取记录 ```php $users = User::where('age', '>', 200)->get(); // 获取年龄大于 200 的用户 [^1] ``` #### 使用 `with` 预加载关联数据 Eloquent ORM 支持预加载关联数据,以减少查询次数并提高性能。例如,假设有一个 `User` 模型关联了 `Post` 模型: ```php $users = User::with('posts')->get(); // 预加载用户的所有帖子 ``` ### 插入数据 插入新记录非常简单,只需创建一个新的模型实例并调用 `save` 方法: ```php $user = new User(); $user->name = 'John Doe'; $user->email = 'john@example.com'; $user->age = 30; $user->save(); ``` ### 更新数据 更新现有记录可以通过检索模型实例,修改其属性,然后调用 `save` 方法来完成: ```php $user = User::find(1); $user->age = 25; $user->save(); ``` ### 删除数据 删除记录可以通过调用模型实例的 `delete` 方法来完成: ```php $user = User::find(1); $user->delete(); ``` ### 使用查询作用域(Query Scopes) 查询作用域允许您将常用的查询逻辑封装到可重用的方法中。例如,定义一个 `AgeScope` 类来过滤年龄大于 200 的用户: ```php namespace App\Scopes; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Scope; class AgeScope implements Scope { public function apply(Builder $builder, Model $model) { $builder->where('age', '>', 200); // 应用年龄过滤条件 } } ``` 然后,在模型中使用该作用域: ```php class User extends Model { protected static function boot() { parent::boot(); static::addGlobalScope(new AgeScope()); // 添加全局作用域 } } ``` ### 批量赋值(Mass Assignment) Laravel 提供了 `$fillable` 和 `$guarded` 属性来控制哪些字段可以被批量赋值。`$fillable` 是一个“白名单”,而 `$guarded` 是一个“黑名单”: ```php class User extends Model { // 只有 name 字段可以被批量赋值 protected $fillable = ['name']; // 白名单设置 [^2] // price 字段不能被批量赋值 protected $guarded = ['price']; // 黑名单设置 [^2] } ``` ### 复杂查询 Laravel ORM 支持构建复杂的查询条件,包括使用 `where` 和 `orWhere` 的组合: ```php $users = User::where(function ($query) { $query->where('gender', 'Male')->where('age', '>=', 18); })->orWhere(function ($query) { $query->where('gender', 'Female')->where('age', '>=', 65); })->get(); // 构建复杂的查询条件 [^3] ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值