Laravel - Eloquent "Has", "With", "WhereHas" - 它们是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30231862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel - Eloquent "Has", "With", "WhereHas" - What do they mean?
提问by lukasgeiter
I've found the concept and meaning behind these methods to be a little confusing, is it possible for somebody to explain to me what the difference between has
and with
is, in the context of an example (if possible)?
我发现这些方法背后的概念和含义有点令人困惑,是否有人可以在示例的上下文中向我解释has
和之间的区别with
(如果可能)?
回答by lukasgeiter
With
和
with()
is for eager loading. That basically means, along the main model, Laravel will preload the relationship(s) you specify. This is especially helpful if you have a collection of models and you want to load a relation for all of them. Because with eager loading you run only one additional DB query instead of one for every model in the collection.
with()
用于急切加载。这基本上意味着,沿着主模型,Laravel 将预加载您指定的关系。如果您有一组模型并且想要为所有模型加载关系,这将特别有用。因为使用预先加载,您只会运行一个额外的数据库查询,而不是为集合中的每个模型运行一个。
Example:
例子:
User > hasMany > Post
User > hasMany > Post
$users = User::with('posts')->get();
foreach($users as $user){
$users->posts; // posts is already loaded and no additional DB query is run
}
Has
已
has()
is to filter the selecting model based on a relationship. So it acts very similarly to a normal WHERE condition. If you just use has('relation')
that means you only want to get the models that have at least one related model in this relation.
has()
是根据关系过滤选择模型。所以它的行为与正常的 WHERE 条件非常相似。如果您只是使用has('relation')
这意味着您只想获得在此关系中至少有一个相关模型的模型。
Example:
例子:
User > hasMany > Post
User > hasMany > Post
$users = User::has('posts')->get();
// only users that have at least one post are contained in the collection
WhereHas
哪里有
whereHas()
works basically the same as has()
but allows you to specify additional filters for the related model to check.
whereHas()
工作原理基本相同,has()
但允许您为相关模型指定额外的过滤器进行检查。
Example:
例子:
User > hasMany > Post
User > hasMany > Post
$users = User::whereHas('posts', function($q){
$q->where('created_at', '>=', '2015-01-01 00:00:00');
})->get();
// only users that have posts from 2015 on forward are returned
回答by TsaiKoga
Documenthas already explain the usage. So I am using SQL to explain these methods
文档已经说明了用法。所以我用SQL来解释这些方法
Example:
例子:
Assuming there is an Order (orders)
has many OrderItem (order_items)
.
假设有一个Order (orders)
has many OrderItem (order_items)
。
And you have already build the relationship between them.
而你已经建立了他们之间的关系。
// App\Models\Order:
public function orderItems() {
return $this->hasMany('App\Models\OrderItem', 'order_id', 'id');
}
These three methods are all based on a relationship.
这三种方法都是基于一种关系。
With
和
Result:with()
return the model object and its related results.
结果:with()
返回模型对象及其相关结果。
Advantage:It is eager-loadingwhich can prevent the N+1 problem.
优点:是eager-loading,可以防止N+1问题。
When you are using the following Eloquent Builder:
当您使用以下 Eloquent Builder 时:
Order::with('orderItems')->get();
Laravel change this code to only two SQL:
Laravel 将此代码更改为只有两个 SQL:
// get all orders:
SELECT * FROM orders;
// get the order_items based on the orders' id above
SELECT * FROM order_items WHERE order_items.order_id IN (1,2,3,4...);
And then laravel merge the results of the second SQLas different from the results of the first SQLby foreign key. At last return the collection results.
然后laravel通过外键合并第二条SQL的结果与第一条SQL的结果不同。最后返回收集结果。
So if you selected columns without the foreign_key in closure, the relationship result will be empty:
因此,如果您选择了闭包中没有外键的列,则关系结果将为空:
Order::with(['orderItems' => function($query) {
// $query->sum('quantity');
$query->select('quantity'); // without `order_id`
}
])->get();
#=> result:
[{ id: 1,
code: '00001',
orderItems: [], // <== is empty
},{
id: 2,
code: '00002',
orderItems: [], // <== is empty
}...
}]
Has
已
Has
will return the model's object that its relationship is not empty.
Has
将返回其关系不为空的模型对象。
Order::has('orderItems')->get();
Laravel change this code to one SQL:
Laravel 将此代码更改为一个 SQL:
select * from `orders` where exists (
select * from `order_items` where `order`.`id` = `order_item`.`order_id`
)
whereHas
哪里有
whereHas
and orWhereHas
methods to put where
conditions on your has
queries. These methods allow you to add customized constraints to a relationship constraint.
whereHas
以及对查询orWhereHas
设置where
条件的方法has
。这些方法允许您向关系约束添加自定义约束。
Order::whereHas('orderItems', function($query) {
$query->where('status', 1);
})->get();
Laravel change this code to one SQL:
Laravel 将此代码更改为一个 SQL:
select * from `orders` where exists (
select *
from `order_items`
where `orders`.`id` = `order_items`.`order_id` and `status` = 1
)