Yii2.0中,关于with多种用法的操作 [ 2.0 版本 ]
我发现,源码上面说了好几种with的使用方法,在这里总结一下【如有错误,请大家帮忙更正,我会及时更改的】
下面我描述下具体的语境:
关联关系:
product表关联的bussiness product.bussiness_id <=> bussiness.id
product关联business_admin product.business_id <=> business_admin
bussiness表关联district表 bussiness.company_province <=> district.id
Model对应的关联:
Product类中与business的关联关系
/**
* 关联partner_product
*/
public function getBussiness()
{
return $this->hasOne(PartnerBusiness::className(), ['id' => 'business_id']);
}
PartnerBusiness类中与district的关联关系
/**
* 关联district 省
*/
public function getProvince()
{
return $this->hasOne(District::className(), ['id' => 'company_province']);
}
/**
* 关联partner_business_admin
*/
public function getBusinessAdmin()
{
return $this->hasMany(PartnerBusinessAdmin::className(), ['business_id' => 'business_id']);
}
例1:这种是比较常用的,简单的一个例子
public function test($id = 13)
{
$result = null;
$id = intval($id);
if ($id) {
$result = self::find()->
select('id, business_id')->
where(['id' => $id])->
with(['bussiness' => function ($query) {
$query->select('id, business_name, company_province');
}])->
asArray()->
one();
$result = $result && is_array($result) ? $result : null;
}
return $result;
}
打印结果如下:
{
"code": 0,
"msg": "success",
"content": {
"id": "13",
"business_id": "13",
"bussiness": {
"id": "13",
"business_name": "大霞",
"company_province": "2"
}
}
}
例2: 这种是通过bussiness间接的获取province对应的信息
public function test($id = 13)
{
$result = null;
$id = intval($id);
if ($id) {
$result = self::find()->
select('id, business_id')->
where(['id' => $id])->
with(['bussiness' => function ($query) {
$query->select('id, business_name, company_province')->
with(['province' => function ($query) {
$query->select('id, name');
}]);
}])->
asArray()->
one();
$result = $result && is_array($result) ? $result : null;
}
return $result;
}
打印结果如下:
{
"code": 0,
"msg": "success",
"content": {
"id": "13",
"business_id": "13",
"bussiness": {
"id": "13",
"business_name": "大霞",
"company_province": "2",
"province": {
"id": "2",
"name": "北京市"
}
}
}
}
说明:
优点: 我们可以通过关联关系查询需要的具体字段信息
缺点: 嵌套层次挺多的,稍有不慎,容易自己迷糊的
例3:此方法也是通过bussiness间接的获取province对应的信息
public function test($id = 13)
{
$result = null;
$id = intval($id);
if ($id) {
$result = self::find()->
select('id, business_id')->
where(['id' => $id])->
with('bussiness.province')->
asArray()->
one();
$result = $result && is_array($result) ? $result : null;
}
return $result;
}
打印结果如下
{
"code": 0,
"msg": "success",
"content": {
"id": "13",
"business_id": "13",
"bussiness": {
"id": "13",
"business_name": "大霞",
"mobile": "xxxxxx",
"weixin": "xxxxx",
"email": "xxxx@163.com",
"company": "xxxx有限公司",
"company_abbr": "xxxx",
"company_logo": "xxxxx.jpg",
"company_slogan": "xxxxxx",
"company_province": "2",
"company_city": "5",
"company_addr": "",
"company_website": "",
"position": "创始人兼CEO",
"revenue_annually": "99999",
"profit_annually": "99999",
"financing": "8",
"company_num": "1",
"service_city": "",
"company_profile": "xxxx",
"employee_id": "0",
"apply_status": "0",
"is_auth": "0",
"settled_auth": "1",
"page_home_recommend": "0",
"created_at": "0",
"updated_at": "1469108008",
"is_show": "0",
"is_del": "0",
"is_del_bak": "0",
"is_need_html": "1",
"ftd_id": "4",
"pay_id": "0",
"user_id": "0",
"come_from": "firmservice",
"reserve_num": "1",
"province": {
"id": "2",
"name": "北京市",
"level": "2",
"usetype": "0",
"upid": "3225",
"displayorder": "0"
}
}
}
}
说明: 其作用和例2大致相同
优点: with关联书写简单,适合表字段比较少的
缺点: 查出了很多不需要的字段信息
例4:product分别关联bussiness, businessAdmin, 即:并列关联
public function test($id = 13)
{
$result = null;
$id = intval($id);
if ($id) {
$result = self::find()->
select('id, business_id')->
where(['id' => $id])->
with('bussiness', 'businessAdmin')->
asArray()->
one();
$result = $result && is_array($result) ? $result : null;
}
return $result;
}
打印结果如下:
{
"code": 0,
"msg": "success",
"content": {
"id": "13",
"business_id": "13",
"bussiness": {
"id": "13",
"business_name": "大霞",
"mobile": "xxxxx",
"weixin": "xxx",
"email": "xxxx@163.com",
"company": "xxx有限公司",
"company_abbr": "股书",
"company_logo": "xxx.jpg",
"company_slogan": "做股权激励,用股书",
"company_province": "2",
"company_city": "5",
"company_addr": "",
"company_website": "",
"position": "创始人兼CEO",
"revenue_annually": "99999",
"profit_annually": "99999",
"financing": "8",
"company_num": "1",
"service_city": "",
"company_profile": "xxxxxxx",
"employee_id": "0",
"apply_status": "0",
"is_auth": "0",
"settled_auth": "1",
"page_home_recommend": "0",
"created_at": "0",
"updated_at": "1469108008",
"is_show": "0",
"is_del": "0",
"is_del_bak": "0",
"is_need_html": "1",
"ftd_id": "4",
"pay_id": "0",
"user_id": "0",
"come_from": "firmservice",
"reserve_num": "1"
},
"businessAdmin": [
{
"id": "161",
"business_id": "13",
"mobile": "xxxx",
"name": "大霞",
"partner_uid": "1898",
"employee_id": "0",
"created_at": "0",
"updated_at": "0",
"is_del": "0",
"is_del_bak": "0"
}
]
}
}
说明:
优点: with关联书写简单,适合表字段比较少的
缺点: 查询信息过多,可能会查出很多我们不需要的字段信息
注意: with('bussiness')->with('businessAdmin') 等价于 with('bussiness')->with('businessAdmin')
总结: 以上就是我看源码总结的with几种方法,各有优点,根据自己的需要可以使用。 不过你知道了例1方法,一般可以解决我们所有问题,但是其他方法总要知道一点,因为万一哪一天我们需要了那,是吧。
感悟: _上面我写的可能有点啰嗦,也有可能描述的有点白话,但是我也是本着“能让你们看懂开头和结尾”的原则,因为我之前看过别人写的博客,虽然很好,但是好多都是没有前因或后果,也有可能我基础比较薄弱看不太懂的缘故; 但是,现在我想把我的理解能够讲出来,若有不对的地方,望见谅,因为我是个小白,也在学习中.
大霞daxia 北京
注册时间:2015-08-27
最后登录:2019-07-23
在线时长:13小时34分
最后登录:2019-07-23
在线时长:13小时34分
- 粉丝33
- 金钱925
- 威望80
- 积分1855
共 5 条评论
赞。。非常赞。学习了。
若两个关联表中 存的关联字段都是 business_id 怎么取?
$result = self::find()-> select('business_id, business_id')->
这个就需要你指定对应的表名了,这样,才能定位到具体表中的字段
非常不错的。
楼主好人啊,谢谢
你可以在 关联方法中 选择需要的字段呀
public function getChildren() { return $this->hasMany(Channel::class, ['pid' => 'channel_id'])->select('pid, channel_id, channel_id as value, channel as label'); }
这应该是对查询的结果集进行字段筛选吧