【CakePHP入門】テーブルを結合(JOIN)して検索する方法

せき
書いた人 せき


侍エンジニア塾ブログは、未経験からWebアプリ開発と仕事獲得をサポートする
侍エンジニア塾のオウンドメディアです。
プログラミング学習を覗き見

こんにちは!フリーエンジニアのせきです。

CakePHPには、関連のあるテーブルを結合して検索する方法がいくつか用意されています。

この記事では、

・関連のあるテーブルをモデルに定義する方法を知りたい
・テーブルを結合して検索する方法を知りたい

という基本的な内容から、

・複数のテーブルと結合する方法を知りたい

といった応用的な内容に関しても解説していきます。

今回はそんなCakePHPでテーブルを結合して検索する方法について、わかりやすく解説します!

モデルを関連付けて検索する方法

サンプルでは、以下のような受注テーブルを作成して、一覧表示します。

テーブル定義

データ

IDCUSTOMER_IDPRODUCT_IDQUANTITY
1122
2221
3231
4313
5332

一覧に顧客名を表示できるよう、顧客テーブルを作成します。

テーブル定義

データ

IDCUSTOMER_NAME
1Tanaka
2Saito
3Yamada

受注テーブル(ACCEPT_ORDER)のCUSTOMER_IDと顧客テーブル(CUSTOMER)のIDが紐づくものとし、受注テーブルに顧客テーブルを結合して検索します。

受注テーブルと顧客テーブルは、1つの顧客IDに対し複数の受注データが存在するので、「多 対 1」という関係になります。

CakePHPのモデルでは、「多 対 1」の関連をbelongsToで定義します。

受注テーブルのModelは以下のようになります。

[プロジェクトのパス]/src/Model/Table/AcceptOrderTable.php
「$this->belongsTo(‘Customer’);」で、顧客テーブルとの関連を定義しています。

テーブルの項目名を「結合するテーブル名_ID」にしておくと、自動でその項目をキーに結合します。

結合される顧客テーブルのModelには、関連の定義は不要です。

[プロジェクトのパス]/src/Model/Table/CustomerTable.php

Entityはそのままです。

[プロジェクトのパス]/src/Model/Entity/AcceptOrder.php
[プロジェクトのパス]/src/Model/Entity/Customer.php

Controllerで検索します。

関連のあるテーブルを結合して検索するには、containを使用し以下のように記述します。

受注テーブルの一覧を表示するControllerです。

[プロジェクトのパス]/src/Controller/AcceptOrderController.php
「$this->AcceptOrder->find(‘all’)->contain([‘Customer’])」で、顧客テーブルと結合しています。

結合したテーブルの値は、以下のように取得できます。

結合したテーブル名は、すべて小文字で記述します。

受注テーブルの一覧を表示するTemplateです。

[プロジェクトのパス]/src/Template/AcceptOrder/index.ctp

「$acceptOrder->customer->CUSTOMER_NAME」で、結合した顧客テーブルの顧客名を表示しています。

「http://[サーバ名]/[プロジェクト名]/acceptOrder」にアクセスすると、以下のように表示されます。
001

検索時にJOINを追加する方法

Modelには手を加えずControllerで検索する時に結合する方法もあります。

検索を行うfind()は、「->」(アロー演算子)を続けて、様々なオプションや条件を指定することができます。

ここではテーブルの結合を行うjoin()leftJoin()を解説します。

join()を使用する方法

join()には、配列で以下のような指定をします。

結合方法には「LEFT」「RIGHT」「INNER」が指定できます。

conditionsに指定した条件で、tableに指定したテーブルと結合します。

さらに、select()を使用して、取得する項目を指定します。

join()を使用したControllerです。

[プロジェクトのパス]/src/Controller/AcceptOrderController.php

テーブルの値は、以下のように取得できます。

これを使用して、Templateは以下のようになります。

[プロジェクトのパス]/src/Template/AcceptOrder/index.ctp

「http://[サーバ名]/[プロジェクト名]/acceptOrder」にアクセスすると、モデルを関連付けて検索した時と同じ画面が表示されます。

leftJoin()を使用する方法

join()で結合方法に「LEFT」を指定する場合には、leftJoin()を使うこともできます

leftJoin()には、以下のような指定をします。

leftJoin()を使用したControllerです。

[プロジェクトのパス]/src/Controller/AcceptOrderController.php

Templateはjoin()の時と同じもので、同じ画面が表示されます。

複数のテーブルと結合する方法

1つのテーブルに、複数のテーブルを結合することもできます。

製品テーブルを作成し、一覧に製品名も表示するようにします。

テーブル定義

データ

IDPRODUCT_NAMEUNIT_PRICE
1Bag5000
2Shoes8000
3Hat3000

Modelに関連を複数定義する場合は、belongsToを追加します。

[プロジェクトのパス]/src/Model/Table/AcceptOrderTable.php

Controllerのcontainにも追加します。

[プロジェクトのパス]/src/Controller/AcceptOrderController.php

製品IDではなく製品名を表示するよう、Templateを修正します。

[プロジェクトのパス]/src/Template/AcceptOrder/index.ctp
「$acceptOrder->product->PRODUCT_NAME」で製品テーブルの製品名が取得できます。

「http://[サーバ名]/[プロジェクト名]/acceptOrder」にアクセスすると、製品名が表示されています。
002

Contorollerのjoin()でも、複数のテーブルを結合することができます。

以下のように、join()にテーブル別名をキーにした連想配列を指定します。

まとめ

今回はテーブルを結合して検索する方法について解説しました。

実際のシステムでは複数のテーブルでデータを管理し、そのデータをユーザが扱いやすいように結合して表示したりするので、テーブルの結合は必須です。

テーブルを結合する方法を忘れてしまったら、この記事を思い出して下さい!


33歳、未経験だった僕がフリーエンジニアになれた理由
現在フリーでWEBエンジニアをやられている濱口直行さん。33歳で、プログラミングを学び始め、約半年という短い期間で独立までされた学習ログを余すことなくインタビューさせていただきました。

プログラミングを学習中の方はもちろん、独立をお考えの方まで幅広く活用できる記事になっています。この機会に是非活用していただければと思います。


未経験者でも安心の徹底サポート!まずは完全無料の体験レッスン!

「プログラミングに興味があるけど未経験だし、、、」とお悩みの方はご安心ください。

  • 24時間質問し放題
  • あなただけのオーダーメイドカリキュラムで学習の効率化
  • 仕事獲得方法からオリジナルアプリ開発方法

侍エンジニア塾では徹底したサポートによる「オーダーメイドカリキュラム」を作成しています。

まずは無料体験レッスンで、「挫折しない学習方法」や「あなただけの学習ロードマップ」を知り、学習の効率化をしましょう。独学の難点である「オリジナルアプリの作り方やエラーの対処法」についてもアドバイスさせていただきます。

詳しいサービス内容は、下記よりご参照ください。

cta_mtm1

非常識な結果を出した卒業生

活躍する現役エンジニア

人気記事セレクション

LINEで送る
Pocket

この記事が気に入ったら
いいね!をしてフォローしよう

最新情報をお届けします

書いた人

せき

せき

フリーランスでWebシステム開発やゲーム開発をしています。
読者の方にプログラミングの面白さをお伝えしたいです。