tp6通过闭包方式连表查询的问题

Posted widgetbox

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tp6通过闭包方式连表查询的问题相关的知识,希望对你有一定的参考价值。

业务背景:

最近在做龙巅广告系统,使用了新的tp6框架

 

相关数据结构:

advert_plan 广告计划表

advert_plan_position 广告计划位置表

这两个表示 计划表和位置表是 1:n

 

需求:

在计划列表中的信息已经是包含跨表信息,其中就有位置表里的信息,那该怎么做呢?

/**
 * 广告计划表
 * Class AdvertPlan
 * @package appcommonmodel
 * @author:hann
 * @time:2020-03-10
 */
namespace appcommonmodel;

class AdvertPlan extends Common {
    
    protected $pk = ‘plan_id‘;

    /**
     * 位置关联模型 1对n
     * User: feng
     * Date: 2020-03-14
     * @return 	hinkmodel
elationHasMany
     */
    public function planPosition() {
        return $this->hasMany(AdvertPlanPosition::class, ‘plan_id‘, ‘plan_id‘);
    }
}

  

写了 在Plan表的model里写关联模型planPosition方法

然后执行查询如下

        //连表查询
        $data = $model_plan->with([‘planPosition‘])
            ->field(‘*‘)
            ->where($where)
            ->order(‘plan_id‘)
            ->paginate();
        echo $model_plan->getLastSql();
        dd($data->toArray());

这样连表查询是没问题的。

 

但问题来了,根据需求,【要根据位置来筛选计划】,那就得设置位置表的where条件呗,代码如下:

    //连表查询,异常
        //haswhere 关联表查询失败!
        $data = $model_plan->with([‘planPosition‘])
            ->field(‘*‘)
            ->where($where)
            ->hasWhere(‘planPosition‘,[‘position‘=>1])
            ->order(‘plan_id‘)
            ->paginate();
        echo $model_plan->getLastSql();
        dd($data->toArray());

 问题来了,提示报错:

#0 [10501]PDOException in PDOConnection.php line 722
SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘AdvertPlan.plan_id‘ in ‘on clause‘

 

 

错误原因:

with不能与hasWhere连用,必须使用with闭包的形式才能实现子模型的条件筛选,具体如下:

       //连表查询
        $data = $model_plan->with(
            [
                ‘planPosition‘	=> function($query) {
                    if(!empty($where_position)){
                        $query->where($where_position);
                    }
                },
            ])
            ->field(‘*‘)
            ->where($where)
            ->order(‘plan_id‘)
            ->paginate();
        echo $model_plan->getLastSql();
        dd($data->toArray());

  技术图片

 

 

 

author:hann

手册链接:https://www.kancloud.cn/manual/thinkphp6_0/1037600

 

以上是关于tp6通过闭包方式连表查询的问题的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL 连表查询及别名用法

MySQL_连表查询

连表查询都用Left Join吧

134 MySQL多表查询

非关心数据库无法进行连表查询 所以我们需要在进行一对多查询时候 无法满足 因此需要在"1"的一方添加"多"的一方的的id 以便用于进行连表查询 ; 核心思想通过

tp6新特性 tp5与tp6异同之处