Yii2.0 - 多层次的链表深层查询及筛选 实现两表三表四表N表关联查询

讲解例子:

用户表 ( user )结构:

id

索引     

username

用户名

department_id

关联部门表ID

部门表 ( department )结构:

id

索引     

name

部门名称

branch_id

关联公司表ID

[1. 单表查询]

user 表的 index 控制器

public function actionIndex(){

    $params = \Yii::$app->request->getQueryParams();

    $query = User::find();

       $res = $query->all();

    return $res;

}

可以获取 user 表的所有数据行构成的数组:

res => [

    0:{ id: 1, username: '用户1', department_id: 1 },

    1:{ id: 2, username: '用户2', department_id: 2 },

    2:{ id: 3, username: '用户3', department_id: 3 }

]

[2. 两表关联查询]

在 user 表的 模型文件 user.php 中加入与department的关联关系

// 建立新字段来获取关联用户的信息
public function extraFields() {
    $fields = [
         // 获取关联部门的信息
         'department' => function ($model) {
            return $model->department;
         },
    ]
}
// 建立用户表的department_id 与 部门表的id 的关联关系
public function getDepartment() {
    return $this->hasOne(Department::class, ['id' => 'department_id']);
}

然后现在再调用 user表的index控制器时,传入 expand 参数.   expand: 'department'

可以获取User表的所有数据行构成的数组,同时每个数据行对象中还会包含department子对象如下:

res => [
    0:{ 
        id: 1, 
        username: '用户1',
        department_id: 1,
        department: {
            id: 1,
            name: '公安部',
            branch_id: 1
        }
    },
    1:{ ... },
    2:{ ... }
]

[3. 三表关联查询]

简单的两表查询,实现了通过查询用户表直接获得部门表某个部门的名称.

那么现在我将建立一个新表: 公司表 branch

id

索引

name

公司名称

现在需要查询用户表的时候,获取到用户的部门,并通过其部门的公司ID获取到其公司,然后得到公司名称

在 user 表的 模型文件 user.php 中已经有了 用户表 与 部门表的关联关系: department

因此现在需要创建一个用户表到公司部的新的关联关系: branch

// 将 department 关联关系 作为中间关系 , 通过 via() 方法实现关联
public function getBranch() {    
    return $this->hasOne(Branch::class, ['id' => 'branch_id'])->via('department')
}

// 然后建立一个新的字段用来装载关联公司信息:
public function extraFields() {
    $fields = [
         // 获取关联部门的信息
         'department' => function ($model) {
            return $model->department;
         },
         // 获取关联公司的信息
          'branch' => function ($model) {
            return $model->branch;
         },
    ]
}

然后现在再调用 user表的index控制器时,传入 expand 参数.   expand: 'department,branch'

可以获取User表的所有数据行构成的数组,同时每个数据行对象中还会包含department和branch子对象如下:

res => [
    0:{
        id: 1,
        username: '用户1',
        department_id: 1,
        department: {
            id: 1,
            name: '综合部',
            branch_id: 1
        },
        branch: {
            id: 1,
            name: '华建电力公司'
        }
    },
    1:{ ... },
    2:{ ... }
]

// 然后通过res[0].branch.name就可以获取分公司名称了

[四表及N表关联的查询]

根据三表的方法,可以得出以下结论: 

   例如 要实现四层链表列表数组的获取(A->B->C->D,  A 要获取 D 的内容) , 需要先建立三层链表的关联关系. 将此关联关系作为中间关系, 通过via()方法来实现关联.

   因此要建立三层链表的关联关系(A->B->C, A 要获取 C 的内容), 需要先建立两层链表的关联关系(A->B, A 要获取 B 的内容), 将两层链表的关联关系作为中间关系, 通过via()方法来实现关联.

   因此无论是A->N的多少层链表关系, 只需要逐级建立关联关系, 然后在查询参数中传入expand=关联关系名 ,即可在查询结果数组里获取到该内容了.

---------------------- 分割线 ----------------------

上面讲的是通过index方法获取列表时的关联查询, 而不是筛选查询, 筛选查询是指传入参数 ( 查询某个字段为什么值 )

筛选查询如何实现多表筛选查询呢? 

  • 1. 筛选部门名称为'综合部'的所有用户. 就是简单的两表关联筛选.

  • 2. 筛选公司名称为'华建电力公司'的所有用户, 就是三表关联筛选.

// 1.默认的用户表的index控制器:
public function actionIndex(){
    $params = \Yii::$app->request->getQueryParams();
    $query = User::find();
       $res = $query->all();
    return $res;
}

// 2. 加入查询判断实现两表关联查询:
public function actionIndex(){
    $params = \Yii::$app->request->getQueryParams();
    $query = User::find();
    // 当传入的参数包含department_name表示通过部门名筛选查询
    if(isset($params['department_name'])) {
       // 通过leftJoin建立用户表与部门表的关联关系
       $query->leftJoin('department', 'user.department_id = department.id');  
       // 然后就可以直接通过部门表的name字段来筛选了
       $query->andWhere(['department.name'=> $params['department_name']]);
    }
    $res = $query->all();
    return $res;
}
// 3. 实现三表关联查询:
public function actionIndex(){
    $params = \Yii::$app->request->getQueryParams();
    $query = User::find();
    // 当传入的参数包含department_name表示通过部门名筛选查询
    if(isset($params['branch_name'])) {
       // 通过leftJoin建立用户表与部门表的关联关系
       $query->leftJoin('department', 'user.department_id = department.id');  
       // 通过leftJoin建立部门表与公司表的关联关系
       $query->leftJoin('branch', 'department.branch_id =branch.id');  
       // 然后就可以直接通过公司表的name字段来筛选了
       $query->andWhere(['branch.name'=> $params['branch_name']]);
    }
    $res = $query->all();
    return $res;
}
// 4. 实现N表关联查询:  就是根据层次使用leftJoin从当前表往目标表建立关联关系
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值