Laravel 在 with 查询中只查询个别字段
刚答了一篇帖子, 算比较常用的技巧,整理一下分享出来。
在使用 Laravel 的关联查询中,我们经常使用 with
方法来避免 N+1
查询,但是 with
会将目标关联的所有字段全部查询出来,对于有强迫症的我们来说,当然是不允许的。
这时候我们可以使用下面的技巧在使用 with 时只查询目标关联的部分字段:
$topics = Topic::limit(2)->with(['user'=>function($query){
$query->select('id','username');
}])->get();
但是每次查询都写得这么繁琐真的好么?不如利用 Laravel 的范围查询将其封装起来:
在 Model 基类中定义一个范围查询(或者使用 Trait)
class BaseModel extends \Eloquent{
public function scopeWithOnly($query, $relation, Array $columns)
{
return $query->with([$relation => function ($query) use ($columns){
$query->select(array_merge(['id'], $columns));
}]);
}
}
在我们普通的 Model 类都继承基类:
class Topic extends BaseModel{
public function user()
{
return $this->belongsTo('User');
}
}
然后使用就很方便了:
$topics = Topic::limit(2)->withOnly('user', ['username'])->get();
本帖已被设为精华帖!
如果关联关系是多层嵌套需要怎么才能实现,例如 ...->with('product.productImg')->get()
就是会不会感觉有点多余,因为我感觉你这样在查的时候也是把要查的字段以数组形式放进去 跟外面写貌似都一样的性质,还是说我理解错了呢
@ruanqi with查询结果空是因为你的查询字段不包含你的关联字段, 就比如 拿ID关联的话, 你就得 select() 里必须包含ID, 要么就返回空
@2016 为啥没有包含关联字段就会为空呢,文档上没找到说明
我想问下 为什么我 的是为空呢 ?
$faqs = Faq::limit(5)
->withOnly('reply', ['id', 'content'])
->get();
是按你说那样在baseModel 中添加了你的那个方法
我直接用with 时查询了所有
我也觉得多余了。
不过可能安全性能好点?比如缺省某些字段。
我改写了一下,因为我主键名不为 id,所以楼主那样就会 null 了。