m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

cakephp3【beta3】クエリービルダーでjoin

1つのテーブルより別のテーブルと紐付ける場合

joinを使用することが可能らしい

containsとかあったけどなんか関連付のイメージがしっくりきていないのでjoinをやってみる

準備

テーブル
CREATE TABLE `members` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `comments` (
  `member_id` int(11) NOT NULL,
  `id` int(11) NOT NULL,
  `data` varchar(255) DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`member_id`, `id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
雛形作成
sh app/bin/cake bake shell sample1
sh app/bin/cake bake model members
sh app/bin/cake bake model comments

サンプル1

join
<?php
namespace App\Shell;

use Cake\Console\Shell;
use Cake\ORM\TableRegistry;

/**
 * Sample1 shell command.
 */
class Sample1Shell extends Shell {

/**
 * main() method.
 *
 * @return bool|int Success or error code.
 */
	public function main() {
		// table
		$members = TableRegistry::get('Members');

		// find
		$query = $members->find()
			->hydrate(false)
			->join([
				'table' => 'comments',
				'alias' => 'c',
				'type' => 'LEFT',
				'conditions' => 'c.member_id = Members.id',
			])->select([
				"id" => "Members.id"
				, "name" => "Members.name"
				, "comments_data" => "c.data"
			]);

		// SQ
		var_dump($query->sql());

		// 出力
		foreach($query as $item){
			var_dump($item);
		}
		
	}

}
出力されたSQL(整形済み)
SELECT 
    Members.id AS `id`, 
    Members.name AS `name`, 
    c.data AS `comments_data` 

FROM 
    members Members 
    LEFT JOIN comments c ON 
        c.member_id = Members.id
抽出できるデータ
array(3) {
  'id' =>
  int(1)
  'name' =>
  string(3) "aaa"
  'comments_data' =>
  string(7) "aaa-111"
}
array(3) {
  'id' =>
  int(1)
  'name' =>
  string(3) "aaa"
  'comments_data' =>
  string(7) "aaa-222"
}
array(3) {
  'id' =>
  int(1)
  'name' =>
  string(3) "aaa"
  'comments_data' =>
  string(7) "aaa-333"
}
array(3) {
  'id' =>
  int(2)
  'name' =>
  string(3) "bbb"
  'comments_data' =>
  string(7) "bbb-111"
}
array(3) {
  'id' =>
  int(3)
  'name' =>
  string(3) "ccc"
  'comments_data' =>
  string(7) "ccc-111"
}
array(3) {
  'id' =>
  int(3)
  'name' =>
  string(3) "ccc"
  'comments_data' =>
  string(7) "ccc-222"
}

まとめ

joinでleftやinnerを使用できる。
その場合は一緒に抽出したいテーブルのカラムはセットしておかないと取得できない

「hydrate」を「false」で指定した場合は配列で項目を取得、「true」の場合はプロパティみたいな感じになる

所感

cakephp3では日本語化が微妙な感じですすんでいる感じ。ただ、まだ英語の方が詳しく書かれているのでそちらしか参考にできない部分があると思います。
なんかだんだんとやっぱりSQLがいいなと思い始めて聞か感じがする。無駄に学習コストがかかると便利には感じないかも…