在yii2.0里面,我们常常会需要关联两个表,我们一般可以这样来操作
$model = (new B2cOrderSearch())->find()->select('*')->join('left join', 'user', 'b2c_order.user_id=user.id');
这样很清晰,是用B2cOrderSearch的model里面的表去关联user,用的是left join还把关联的字段也写了,但是这样我们每一次都需要去写这个关联的字段,这样感觉不是十分合理,有没有其它的办法呢,有的,用hasOne或者hasMany
首先,我们需要在model里面定义好关系
public function getOrders() {
//客户和订单是一对多的关系所以用hasMany
//此处OrdersModel在CustomerModel顶部别忘了加对应的命名空间
//id对应的是OrdersModel的id字段,order_id对应CustomerModel的order_id字段
return $this->hasMany(OrdersModel::className(), ['id' => 'order_id']);
}
public function getCountry() {
//客户和国家是一对一的关系所以用hasOne
return $this->hasOne(CountrysModel::className(), ['id' => 'Country_id']);
}
这里有几个需要注意的
- 方法的名称必须是get****(此处***是表的名称,首字母大写)
- has***里面的参数,第一个是关联的表的名称(这里用了方法来调用,避免gii以后改变了),第二个参数是一个数组。a=>b,a是关联表用于关联的字段,b是当前表的字段
我们这样定义好了以后,就可以使用了
很简单
// 查询客户与他们的订单和国家
CustomerModel::find()->with('orders', 'country')->all();
// 查询客户与他们的订单和订单关联的发货地址(注:orders 与 address都是关联关系)
CustomerModel::find()->with('orders.address')->all();
// 查询客户与他们的国家和状态为1的订单
CustomerModel::find()->with([
'orders' => function ($query) {
$query->andWhere('status = 1');
},
'country',
])->all();
可以看到,我们定义了以后,可以直接关联两个表,在一个with里面,而且这是一个AR,我们可以对其进行链式操作等,还有。出来的数据的list里面,没一个会有你所关联的表的字段的一个数组,这个数组里面包含了关联的数据(具体可以自己去试一下)