CakePHP-Suchmethode mit JOIN

Lesezeit: 5 Minuten

CakePHP Suchmethode mit JOIN
geoffs3310

Hallo,

Ich muss die folgende Abfrage mit CakePHP durchführen find Methode:

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

Grundsätzlich habe ich:

  • messages Tisch mit A Message Modell
  • users Tisch mit User Modell

und Informationen aus beiden Tabellen in einer Abfrage abrufen möchten. Die users.id Feld ist das gleiche wie das messages.from Feld, also ist das, was der Join ist.

Ich mache es in meinem MessagesController also müsste es so etwas sein:

$this->Message->find();

Danke

CakePHP Suchmethode mit JOIN
Stefan

Es gibt zwei Möglichkeiten, wie Sie dies tun können. Einer von ihnen ist der Standard-CakePHP-Weg, und der andere verwendet einen benutzerdefinierten Join.

Es sei darauf hingewiesen, dass dieser Ratschlag für CakePHP 2.x gilt, nicht für 3.x.

Der CakePHP-Weg

Sie würden eine Beziehung mit Ihrem Benutzermodell und Ihrem Nachrichtenmodell erstellen und das Containable-Verhalten verwenden:

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

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

Sie müssen die ändern messages.from Spalte zu sein messages.user_id damit Cake die Datensätze automatisch für Sie zuordnen kann.

Dann können Sie dies vom Nachrichten-Controller aus tun:

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

Der (andere) CakePHP-Weg

Ich empfehle, die erste Methode zu verwenden, da Sie dadurch viel Zeit und Arbeit sparen. Die erste Methode leistet auch die Grundlagen für das Einrichten einer Beziehung, die für eine beliebige Anzahl anderer Suchaufrufe und -bedingungen neben der gerade benötigten verwendet werden kann. CakePHP unterstützt jedoch eine Syntax zum Definieren eigener Joins. Es würde so gemacht werden, von der 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'
));

Beachten Sie, dass ich den Feldnamen belassen habe messages.from das gleiche wie Ihre aktuelle Tabelle in diesem Beispiel.

Verwenden von zwei Beziehungen zu demselben Modell

So können Sie das erste Beispiel mit zwei Beziehungen zu demselben Modell ausführen:

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'
        )
    );
}

Jetzt können Sie Ihren Suchaufruf wie folgt durchführen:

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

  • Hallo, danke für Ihre Antwort, ich kann den Namen der Spalte messages.from nicht ändern, weil ich auch eine Spalte messages.to habe, die die Benutzer-ID des Empfängers enthält, also kann ich keine zwei user_id-Felder haben. Ich kann es mit meiner MySQL-Abfrage ganz einfach machen. Gibt es keine einfache Möglichkeit, dies in Cake zu tun, ohne meine Tabellen ändern zu müssen?

    – geoffs3310

    22. Februar 2011 um 15:23 Uhr

  • Ich habe es ‘auf die (andere) Cakephp-Weise’ gemacht, ich denke, das ist viel besser. Danke für all deine Hilfe, du bist ein Lebensretter!

    – geoffs3310

    22. Februar 2011 um 15:31 Uhr

  • @geoffs3310 Hat dir im dritten Beispiel einen noch besseren Weg gegeben.

    – Stefan

    22. Februar 2011 um 15:37 Uhr

  • @Stephen, ich möchte jetzt so etwas tun, aber das habe ich gehört contain bewirkt, dass intern eine zusätzliche Abfrage für jede Zeile der Haupttabelle ausgeführt wird … anstatt nur eine einzelne Abfrage mit einem Join durchzuführen. Gedanken dazu?

    – Dallas

    20. Februar 2014 um 1:56 Uhr

  • @smerny Ich bin mir nicht sicher, aber Sie könnten sich Ihre SQL-Protokolle ansehen, um dies zu überprüfen.

    – Stefan

    21. Februar 2014 um 17:47 Uhr

1645913047 659 CakePHP Suchmethode mit JOIN
Sergio

Anderes Beispiel, benutzerdefinierte Datenpaginierung für JOIN

CODE im Controller CakePHP 2.6 ist OK:

$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));

ODER Beispiel 2, NICHT aktive Bedingungen:

$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'
                        )
                    ),
                ),
            )
        );

Es geht zum Array ist null.

868710cookie-checkCakePHP-Suchmethode mit JOIN

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy