应用Yii2框架进行开发时,常常会遇到多表联结查问的场景,利用Yii自带的AR类,能够很不便的进行多表联结查问操作。
如果应用的是AR的话,在进行多表联结查问时,须要提前在相干的model层对相干的数据表模型进行hasOne()或hasMany()操作,即申明关联关系。
hasOne()或hasMany()的具体应用办法和实现原理,能够在YII的官方网站的文档中进行查问,这里只说一下hasOne()和hasMany()在应用过程中常常会遇到的一个操作,分页查问,以及应用hasMany()时产生的一个数据问题,所查问的数据不精确。具体用代码举例说明。

1:假如有两张表item(商品表),item_sku(商品sku表),它们的对应关系是 1:N,即一个商品能够有多个对应的sku数据,那么在item的model层申明关联类型时,大略如下:
public function getSku()
{
return $this->hasMany(ItemSku::className(), ['item_id' => 'id']);
}

2:咱们在item的controller层进行api编写时,个别分页查问如下:
$result = Item::find()->joinwith('sku')->offset(0)->limit(10)->all();

3:此时如果咱们对$result进行 count()计算,假如mysql数据库中的item数据>50条,但往往得出的后果可能只是7或者5,8之类的数据,而不是咱们想要的10条数据。

网上查了很多材料,比拟靠谱的解释是,因为是1对多的关系,记录总数是子表的记录数(即ItemSku表),而子表的数据会有反复数据,进而导致数据不准。解决的办法也很简略,即在查问语句中加上distinct(),即
$result = Item::find()->joinwith('sku')->offset(0)->limit(10)->distinct()->all();
这样,因为记录数据去重后,即失去了所需的数据。