查询 Laravel 中的集合
Querying collections in Laravel
我是否理解正确,当我查询 Laravel 集合时,它不会查询数据库,而是对已获取的内容执行查询?
例如,我有一个关系 returns 一个集合:
public function permissions()
{
return $this->belongsToMany(Permission::class, RolePermission::getModelTable(), 'role_id', 'permission_id');
}
以下代码是查询数据库还是使用 php 工具处理集合?
$role->permissions->where('code','global.test')->count()
而且,据我所知,如果我查询关系,那么将查询数据库,而不是使用已经获取的结果:
$role->permissions()->where('code','global.test')->count()
所以基本上,$role->permissions - 使用获取的结果 "offline",但是 $role->permissions() - 查询数据库
什么方式通常更有效?什么时候?
你基本上是对的。调用 $role->permissions
和 $role->permissions()
的区别在于第一个 returns 是 Collection
的实例,而第二个 returns 是 BelongsToMany
的实例。
Collection
是相关对象的集合(真的吗?),而 BelongsToMany
是关系本身。所以是的,通过调用方法(而不是魔术 属性),您正在查询数据库。
更新
我没听懂最后一个问题,抱歉。
第一次调用 $role->permissions
(魔术 属性)时,Laravel 获取所有与 $role
关联的权限,如果它们不是 eager loaded。如果您只需要这些权限的一个子集,您可以使用任何魔术 属性 和方法来过滤它们。让我举一些例子。
$role = Role::first();
// Fetch all the permissions and count a subset.
$role->permissions->where('code', 'global.test')->count();
// Count another subset.
$role->permissions->where('code', 'another.test')->count();
同样可以使用以下方法完成:
$role = Role::first();
// Fetch a subset of the permissions and count it.
$role->permissions()->where('code', 'global.test')->count();
// Fetch another subset and count it.
$role->permissions()->where('code', 'another.test')->count();
如您所见,在第一个示例中,您只进行了一次查询并以不同方式过滤结果。在第二个示例中,您进行了两个查询。第一个显然效率更高
但是,如果您在同一次执行期间只需要一个子集,情况就会发生变化。这里我们使用 eager loading:
$role = Role::with('permissions', function($query) {
// Here we filter the related permissions.
$query->where('code', 'global.test');
})->first();
// We have what we want. No need to filter the collection.
$role->permissions->count();
// Let's do something else with this subset.
$role->permissions->all();
如果您获取所有相关对象,但只需要那个子集怎么办?
$role = Role::first();
// Filter the collection to count the needed subset.
$role->permissions->where('code', 'global.test')->count();
// Filter the collection to get the needed subset.
$role->permissions->where('code', 'global.test')->all();
大家可以看到,在第二个例子中我们就少了很多DRY,同样的操作也是多次进行。当然效率较低。
我是否理解正确,当我查询 Laravel 集合时,它不会查询数据库,而是对已获取的内容执行查询?
例如,我有一个关系 returns 一个集合:
public function permissions()
{
return $this->belongsToMany(Permission::class, RolePermission::getModelTable(), 'role_id', 'permission_id');
}
以下代码是查询数据库还是使用 php 工具处理集合?
$role->permissions->where('code','global.test')->count()
而且,据我所知,如果我查询关系,那么将查询数据库,而不是使用已经获取的结果:
$role->permissions()->where('code','global.test')->count()
所以基本上,$role->permissions - 使用获取的结果 "offline",但是 $role->permissions() - 查询数据库
什么方式通常更有效?什么时候?
你基本上是对的。调用 $role->permissions
和 $role->permissions()
的区别在于第一个 returns 是 Collection
的实例,而第二个 returns 是 BelongsToMany
的实例。
Collection
是相关对象的集合(真的吗?),而 BelongsToMany
是关系本身。所以是的,通过调用方法(而不是魔术 属性),您正在查询数据库。
更新
我没听懂最后一个问题,抱歉。
第一次调用 $role->permissions
(魔术 属性)时,Laravel 获取所有与 $role
关联的权限,如果它们不是 eager loaded。如果您只需要这些权限的一个子集,您可以使用任何魔术 属性 和方法来过滤它们。让我举一些例子。
$role = Role::first();
// Fetch all the permissions and count a subset.
$role->permissions->where('code', 'global.test')->count();
// Count another subset.
$role->permissions->where('code', 'another.test')->count();
同样可以使用以下方法完成:
$role = Role::first();
// Fetch a subset of the permissions and count it.
$role->permissions()->where('code', 'global.test')->count();
// Fetch another subset and count it.
$role->permissions()->where('code', 'another.test')->count();
如您所见,在第一个示例中,您只进行了一次查询并以不同方式过滤结果。在第二个示例中,您进行了两个查询。第一个显然效率更高
但是,如果您在同一次执行期间只需要一个子集,情况就会发生变化。这里我们使用 eager loading:
$role = Role::with('permissions', function($query) {
// Here we filter the related permissions.
$query->where('code', 'global.test');
})->first();
// We have what we want. No need to filter the collection.
$role->permissions->count();
// Let's do something else with this subset.
$role->permissions->all();
如果您获取所有相关对象,但只需要那个子集怎么办?
$role = Role::first();
// Filter the collection to count the needed subset.
$role->permissions->where('code', 'global.test')->count();
// Filter the collection to get the needed subset.
$role->permissions->where('code', 'global.test')->all();
大家可以看到,在第二个例子中我们就少了很多DRY,同样的操作也是多次进行。当然效率较低。