你好
我需要使用CakePHP find方法执行以下查询:
find
SELECT * FROM `messages` INNER JOIN users ON messages.from = users.id WHERE messages.to = 4 ORDER BY messages.datetime DESC
基本上我有:
messages
Message
users
User
并希望在一个查询中从两个表中检索信息。该users.id字段与该messages.from字段相同,因此就是连接所在的位置。
users.id
messages.from
我正在做我的事情,MessagesController所以它需要是这样的:
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可以自动为您关联记录。
messages.user_id
然后,您可以从消息控制器执行此操作:
$this->Message->find('all', array( 'contain' => array('User') 'conditions' => array( 'Message.to' => 4 ), 'order' => 'Message.datetime DESC' ));
我建议使用第一种方法,因为它将节省大量时间和工作。第一种方法还为建立关系奠定了基础,该关系可以用于除您现在需要的其他多个查找调用和条件。但是,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' ));