关联模型最大的优势是关联好了模型,我们不必再代码中写那么多的表关联来取数据,可以简单的几行代码即可取出复杂的关联模型数据。
此处主要想说下N+1
的问题。
其实N+1 使用with的本质是在首次查询中使用了whereIn查询,比如一个订单表关联的表
public function getById($id, $userId = 0)
{
$query = $this->model->where('mall_order_id', $id);
if ($userId) {
$query = $query->where('user_id', $userId);
}
$query = $query->with(
'belongsToOneUser', // 关联一个用户
'hasManyDetail.belongsToOneCommodity', // 关联订单详情中的一个商品
'hasManyDetail.belongsToOneSku', // 关联订单详情中的一个sku_id
'belongsToOneMerchant' // 关联一个门店
);
return $query->first();
}
图片.png
可以看到一条语句是把所有的关联数据都给取出来了
这个时候,我们取订单值
应该使用
$orderlList = $order->hasManyDetail;
这种方式可能是框架中有一定的规则,会直接在$order对象中取 has_many_detail 的值
如果使用以下方式,则会重新生成一条sql查询,既产生N+1的问题
$orderlList = $order->hasManyDetail()->get();
注意:
-
既然解决的是
N+1
问题,那么 如果是只查询一条语句,就不需要使用with()
。因为他是使用whereIn([n])
也就是数组中只有一个值的方式查询的,这种方式反而不如直接查询。 -
但是如果你要关联一个模型中的模型,那么你可以继续使用
with()
方法。
比如我上面的sql
其实可以优化成
$query = $query->with(
'hasManyDetail.belongsToOneCommodity',
'hasManyDetail.belongsToOneSku'
);
网友评论