大霞daxia 2016-12-01 15:55:39 26062次浏览 5条评论 17 9 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方法,一般可以解决我们所有问题,但是其他方法总要知道一点,因为万一哪一天我们需要了那,是吧。


感悟: _上面我写的可能有点啰嗦,也有可能描述的有点白话,但是我也是本着“能让你们看懂开头和结尾”的原则,因为我之前看过别人写的博客,虽然很好,但是好多都是没有前因或后果,也有可能我基础比较薄弱看不太懂的缘故; 但是,现在我想把我的理解能够讲出来,若有不对的地方,望见谅,因为我是个小白,也在学习中.
觉得很赞
  • 评论于 2016-12-22 15:16 举报

    赞。。非常赞。学习了。

  • 评论于 2017-01-16 11:48 举报

    若两个关联表中 存的关联字段都是 business_id 怎么取?

     $result = self::find()->
                select('business_id, business_id')->
    
    1 条回复
    评论于 2017-01-18 10:52 回复

    这个就需要你指定对应的表名了,这样,才能定位到具体表中的字段

  • 评论于 2017-08-09 00:24 举报

    非常不错的。

  • 评论于 2017-11-03 16:35 举报

    楼主好人啊,谢谢

  • 评论于 2018-05-31 19:16 举报

    你可以在 关联方法中 选择需要的字段呀

    public function getChildren()
    {
        return $this->hasMany(Channel::class, ['pid' => 'channel_id'])->select('pid, channel_id, channel_id as value, channel as label');
    }
    
    1 条回复
    评论于 2019-05-24 10:42 回复

    这应该是对查询的结果集进行字段筛选吧

您需要登录后才可以评论。登录 | 立即注册