CakePHP使用JOIN查找方法

嗨,

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

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

基本上我有:

  • messages模型的messages
  • users表与User模型

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

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

 $this->Message->find(); 

谢谢

有两种主要方法可以做到这一点。 其中之一是标准的CakePHP方式,另一种是使用自定义连接。

值得指出的是,这个build议是针对CakePHP 2.x的,而不是3.x.

CakePHP的方式

您将创build与您的用户模型和消息模型的关系,并使用可容纳的行为:

 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.from ,以便Cake可以为您自动关联logging。

那么你可以通过消息控制器来做到这一点:

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

(其他)CakePHP方式

我build议使用第一种方法,因为它会为您节省大量的时间和工作。 第一种方法也build立了一个关系,除了你现在需要的关系之外,还可以用于任何数量的查找调用和条件。 但是,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' )); 

Otro示例,用于JOIN的自定义数据分页

控制器CakePHP 2.6中的代码正常:

 $this->SenasaPedidosFacturadosSds->recursive = -1; // Filtro $where = array( 'joins' => array( array( 'table' => 'usuarios', 'alias' => 'Usuarios', 'type' => 'INNER', 'conditions' => array( 'Usuarios.usuario_id = SenasaPedidosFacturadosSds.usuarios_id' ) ), array( 'table' => 'senasa_pedidos', 'alias' => 'SenasaPedidos', 'type' => 'INNER', 'conditions' => array( 'SenasaPedidos.id = SenasaPedidosFacturadosSds.senasa_pedidos_id' ) ), array( 'table' => 'clientes', 'alias' => 'Clientes', 'type' => 'INNER', 'conditions' => array( 'Clientes.id_cliente = SenasaPedidos.clientes_id' ) ), ), 'fields'=>array( 'SenasaPedidosFacturadosSds.*', 'Usuarios.usuario_id', 'Usuarios.apellido_nombre', 'Usuarios.senasa_establecimientos_id', 'Clientes.id_cliente', 'Clientes.consolida_doc_sanitaria', 'Clientes.requiere_senasa', 'Clientes.razon_social', 'SenasaPedidos.id', 'SenasaPedidos.domicilio_entrega', 'SenasaPedidos.sds', 'SenasaPedidos.pt_ptr' ), 'conditions'=>array( 'Clientes.requiere_senasa'=>1 ), 'order' => 'SenasaPedidosFacturadosSds.created DESC', 'limit'=>100 ); $this->paginate = $where; // Get datos $data = $this->Paginator->paginate(); exit(debug($data)); 

或者示例2,非主动条件:

 $this->SenasaPedidosFacturadosSds->recursive = -1; // Filtro $where = array( 'joins' => array( array( 'table' => 'usuarios', 'alias' => 'Usuarios', 'type' => 'INNER', 'conditions' => array( 'Usuarios.usuario_id = SenasaPedidosFacturadosSds.usuarios_id' ) ), array( 'table' => 'senasa_pedidos', 'alias' => 'SenasaPedidos', 'type' => 'INNER', 'conditions' => array( 'SenasaPedidos.id = SenasaPedidosFacturadosSds.senasa_pedidos_id' ) ), array( 'table' => 'clientes', 'alias' => 'Clientes', 'type' => 'INNER', 'conditions' => array( 'Clientes.id_cliente = SenasaPedidos.clientes_id', 'Clientes.requiere_senasa = 1' ) ), ), 'fields'=>array( 'SenasaPedidosFacturadosSds.*', 'Usuarios.usuario_id', 'Usuarios.apellido_nombre', 'Usuarios.senasa_establecimientos_id', 'Clientes.id_cliente', 'Clientes.consolida_doc_sanitaria', 'Clientes.requiere_senasa', 'Clientes.razon_social', 'SenasaPedidos.id', 'SenasaPedidos.domicilio_entrega', 'SenasaPedidos.sds', 'SenasaPedidos.pt_ptr' ), //'conditions'=>array( // 'Clientes.requiere_senasa'=>1 //), 'order' => 'SenasaPedidosFacturadosSds.created DESC', 'limit'=>100 ); $this->paginate = $where; // Get datos $data = $this->Paginator->paginate(); exit(debug($data)); 
  $services = $this->Service->find('all', array( 'limit' =>4, 'fields' => array('Service.*','ServiceImage.*'), 'joins' => array( array( 'table' => 'services_images', 'alias' => 'ServiceImage', 'type' => 'INNER', 'conditions' => array( 'ServiceImage.service_id' =>'Service.id' ) ), ), ) ); 

数组是空的。