如何使用 CakePHP 3 连接多个表?

Posted

技术标签:

【中文标题】如何使用 CakePHP 3 连接多个表?【英文标题】:How to join multiple tables using CakePHP 3? 【发布时间】:2015-08-05 11:34:42 【问题描述】:

我正在使用 Cakephp 3.x。

我想要的是能够调用 $this->Categories->find() 然后加入 Topics.cat_id = Categories.id 上的主题,然后加入 Posts.topic_id = Topics.id 上的帖子。

我没有收到任何错误,但我得到的唯一数据是类别数据,我尝试了 LEFT 和 INNER 连接但没有成功。任何帮助将不胜感激。

表关系为:

分类表

$this->hasMany('Topics');

主题表

$this->belongsTo('Categories');
$this->hasMany('Posts');

帖子表

$this->belongsTo('Topics');

还有我的查询:

$query = $this->Categories->find('all')
        ->order(['Categories.name' => 'ASC'])
        ->join([
            'topics' => [
                'table' => 'Topics',
                'type' => 'LEFT',
                'conditions' => 'topics.Cat_id = Categories.id'
            ],
            'posts' => [
                'table' => 'Posts',
                'type' => 'LEFT',
                'conditions' => 'posts.topic_id = topics.id'
            ]
        ]);

尝试使用可包含的行为,但现在我使用此查询收到错误“类别与帖子不关联”:

$query = $this->Categories->find('all')
        ->order(['Categories.name' => 'ASC'])
        ->contain(['Topics', 'Posts' => function($q)
            return $q->where(['Posts.topic_id' => 'Topics.id']);
        ]);

【问题讨论】:

您正在寻找包含,而不是手动连接。 book.cakephp.org/3.0/en/orm/… @ndm 感谢您的回复。我已经用包含的结果更新了我的问题,有什么建议吗? 仔细看看如何定义嵌套关联。 【参考方案1】:

根据@ndm 的建议,我能够得到我想要的结果。我一定忽略了文档中的部分,所以其他遇到此问题的人,这里是如何做到的。

$query = $this->Categories->find('all')
        ->order(['Categories.name' => 'ASC'])
        ->contain([
            'Topics.Posts.Users'
        ]);

【讨论】:

->contain(['Topics.Posts.Users' 我不知道你能做到这一点,我花了一整天的时间试图弄清楚。 如何从三个表中获取数据?例如我有三个表:A,B,C。我需要左连接所有三个表。该怎么做?【参考方案2】:

只要找到cakephp2的那种遗留,你仍然可以像旧版本一样使用join。

$result = $this->Category->findAll(fields=>['id','Topic.id'], 'conditions'=>['Topic.name'=>'s'],'join'=>['Topic' => [
            'table' => 'topics',
            'type' => 'INNER',
            'conditions' => 'Topic.category_id = Category.id'
        ]]);

觉得熟悉?你仍然可以像以前一样使用别名

第一次回答,不知道代码编辑器是如何工作的,抱歉。

【讨论】:

我不知道有join() 方法。谢谢指点。【参考方案3】:

试试这个:

 $query = $this->Categories->find('all')
        ->fields('Categories.*', 'Topics.*', 'Posts.*')
        ->order(['Categories.name' => 'ASC'])
        ->join([
            'topics' => [
                'table' => 'Topics',
                'type' => 'LEFT',
                'conditions' => 'topics.Cat_id = Categories.id'
            ],
            'posts' => [
                'table' => 'Posts',
                'type' => 'LEFT',
                'conditions' => 'posts.topic_id = topics.id'
            ]
        ]);

添加这一行:

->fields('Categories.*', 'Topics.*', 'Posts.*')

从主题和帖子中检索数据

【讨论】:

这不起作用的原因有很多,没有名为fields()的方法,选择字段是通过select()完成的,但是ORM查询构建器不支持.*,它将被别名并导致无效的 SQL,非包含关联上的其他字段也不会被水合,并且由于存在 1:n 关系等,您会得到重复的结果...

以上是关于如何使用 CakePHP 3 连接多个表?的主要内容,如果未能解决你的问题,请参考以下文章

CakePHP 3 - 使用多个数据库连接*不使用ORM *

在 cakephp 2.x 中如何使用连接表获取第三个表数据?

CakePHP 3 连接表关联

如何将数据写入 CakePHP 中 HABTM 连接表的 HABTM 关联?

Cakephp Auth 与多个“用户”表

如何使用递归模型创建 cakephp 表单