当前位置: 首页 > 面试题库 >

CakePHP使用JOIN查找方法

龚俊捷
2023-03-14
问题内容

你好

我需要使用CakePHP find方法执行以下查询:

SELECT *
FROM `messages`
INNER JOIN users ON messages.from = users.id
WHERE messages.to = 4
ORDER BY messages.datetime DESC

基本上我有:

  • messagesMessage模型的桌子
  • usersUser模型的桌子

并希望在一个查询中从两个表中检索信息。该users.id字段与该messages.from字段相同,因此就是连接所在的位置。

我正在做我的事情,MessagesController所以它需要是这样的:

$this->Message->find();

谢谢


问题答案:

您可以通过两种主要方法来执行此操作。其中一种是标准的CakePHP方法,另一种是使用自定义联接。

值得指出的是,此建议适用于CakePHP 2.x,而不是3.x。

您将与用户模型和消息模型创建关系,并使用可包含的行为:

class User extends AppModel {
    public $actsAs = array('Containable');
    public $hasMany = array('Message');
}

class Message extends AppModel {
    public $actsAs = array('Containable');
    public $belongsTo = array('User');
}

您需要将messages.from列更改为,messages.user_id以便cake可以自动为您关联记录。

然后,您可以从消息控制器执行此操作:

$this->Message->find('all', array(
    'contain' => array('User')
    'conditions' => array(
        'Message.to' => 4
    ),
    'order' => 'Message.datetime DESC'
));

(其他)CakePHP方式

我建议使用第一种方法,因为它将节省大量时间和工作。第一种方法还为建立关系奠定了基础,该关系可以用于除您现在需要的其他多个查找调用和条件。但是,cakePHP确实支持用于定义自己的联接的语法。可以这样进行MessagesController

$this->Message->find('all', array(
    'joins' => array(
        array(
            'table' => 'users',
            'alias' => 'UserJoin',
            'type' => 'INNER',
            'conditions' => array(
                'UserJoin.id = Message.from'
            )
        )
    ),
    'conditions' => array(
        'Message.to' => 4
    ),
    'fields' => array('UserJoin.*', 'Message.*'),
    'order' => 'Message.datetime DESC'
));

注意,messages.from在此示例中,我将字段名称保留为与当前表相同的名称。

对同一模型使用两个关系

这是将两个关系应用于同一模型的第一个示例:

class User extends AppModel {
    public $actsAs = array('Containable');
    public $hasMany = array(
        'MessagesSent' => array(
            'className'  => 'Message',
            'foreignKey' => 'from'
         )
    );
    public $belongsTo = array(
        'MessagesReceived' => array(
            'className'  => 'Message',
            'foreignKey' => 'to'
         )
    );
}

class Message extends AppModel {
    public $actsAs = array('Containable');
    public $belongsTo = array(
        'UserFrom' => array(
            'className'  => 'User',
            'foreignKey' => 'from'
        )
    );
    public $hasMany = array(
        'UserTo' => array(
            'className'  => 'User',
            'foreignKey' => 'to'
        )
    );
}

现在,您可以像这样进行查找呼叫:

$this->Message->find('all', array(
    'contain' => array('UserFrom')
    'conditions' => array(
        'Message.to' => 4
    ),
    'order' => 'Message.datetime DESC'
));


 类似资料:
  • 问题内容: 我有两个表: 这是我的查询: 并为此: 它在第一个表上使用的全索引扫描进行排序,但不使用y索引进行连接(在解释中)。这对性能非常不利,并且会杀死整个数据库服务器,因为这是一个非常频繁的查询。 我尝试使用反转表顺序,但这给了,甚至更糟。 有什么办法可以使mysql同时使用索引进行连接和排序? ===更新=== 我真的很绝望。也许某种形式的非规范化可以在这里有所帮助? 问题答案: 如果您有

  • 我正在使用Spring Boot和JDBCT模板开发一个用于数据库查询的应用程序。 问题是这样的:如果我必须在一个表上询问db,我没有问题。但是,如果我有一个join,我该如何执行这个任务? 更具体地说,创建表的SQL命令如下: 对应的java类如下: 约束是 firewall_Items.firewall_id = firewall.id(因此,这些是我必须用来执行 join 的变量)。 现在,

  • 本文向大家介绍浅谈java线程join方法使用方法,包括了浅谈java线程join方法使用方法的使用技巧和注意事项,需要的朋友参考一下 本博客简介介绍一下java线程的join方法,join方法是实现线程同步,可以将原本并行执行的多线程方法变成串行执行的 如图所示代码,是并行执行的 打印出来的信息,都是这样的 执行时间:0 线程1:1 线程2:1 线程2:2 线程2:3 线程2:4 线程2:5 线

  • 本文向大家介绍JavaScript中join()方法的使用简介,包括了JavaScript中join()方法的使用简介的使用技巧和注意事项,需要的朋友参考一下  JavaScript数组join()方法加入数组的所有元素为一个字符串。 语法 下面是参数的详细信息:     separator : 指定字符串分开数组的每个元素。如果省略,则数组元素用逗号分隔。 返回值: 返回接合所有数组元素之后的字

  • 我有一些自定义的find方法,我经常使用它们来代替WebDriver。findElement和WebDriver。findElements。这些方法接受一个自定义定位器对象,该对象包含By定位器和正则表达式,并返回与By定位器匹配且其文本与正则表达式匹配的一个或多个WebElement。 这些在很多场合都非常有用,我想为WebElement提供同样的功能。findElement和WebElemen

  • 本文向大家介绍关于laravel 子查询 & join的使用,包括了关于laravel 子查询 & join的使用的使用技巧和注意事项,需要的朋友参考一下 本项目中关联了2个数据库 在某个需求中,需要使用子查询获取snapshot快照表库的关联数据,从而实现以下sql逻辑 其中子查询主要用到以下query builder语句 而join语句中可传入匿名函数重新构造,如再其中加多几个连接条件,或者查