73114


containメソッドとjoinメソッドの違いが分かっておりません。  
テーブルを結合する際にデータを取得する際は下記のようにcontainメソッドを使用  
した後にjoinメソッドを使用するべきなのでしょうか。  
containメソッドを使用せずにjoinメソッドのみを使用しただけでもテーブルが結合できて  
データ取得できているようでよくわかっていません。  
ご教授お願い致します。

[code]

    class UserInfoTable extends Table {
        public function initialize(array $config) {
            parent::initialize($config);
    
            $this->hasMany('Comments',[
                'joinType' => 'INNER',
                'foreignKey' => ['loginid'],
                'bindingKey' => ['loginid']
            ]);
    
        public function findData(Query $query, array $options)
        {
            $query->contain(['Comments']);
            $query->join([
                'table' =>'comments',
                'alias' => 'c',
                'conditions' => 'UserInfo.loginid = c.loginid',
            ])
            ->where([
                'UserInfo.name' => $options['name']
            ])
            ->select([
                'id' => 'UserInfo.id',
                'name' => 'UserInfo.name',
                'testDesu' => 'UserInfo.mailaddress',
                'title' => '.title',
            ]);
    
[/code]


CC BY-SA 4.0
2021-01-03T14:04:00.677
73046
2021-01-06T03:31:39.857
17348
question
php cakephp
cakephp3のテーブル結合について


基本は `contain` のみを使用すればよいです。  
CakePHP 3以降においてTableクラスを使用しているのであれば、クエリビルダーで `join` メソッドを使用する機会はほぼありません。

`join`は元のテーブルに他のテーブルを結合した結果を得る操作です。

参考: [SQLで「テーブルの結合」を行う (1/3)：「データベーススペシャリスト試験」戦略的学習のススメ（13） -
＠IT](https://www.atmarkit.co.jp/ait/articles/1703/01/news186.html)

質問にあるコードのjoin操作であれば、UserInfoに紐付いているCommentsのレコード分、UserInfoのレコードが返ってきます。

例)

UserInfo

id | loginid | name  
---|---|---  
1 | 1 | User A  
2 | 2 | User B  
3 | 3 | User C  
  
Comments

id | loginid | title  
---|---|---  
1 | 1 | Comment A  
2 | 1 | Comment B  
3 | 1 | Comment C  
4 | 2 | Comment D  
5 | 2 | Comment E  
  
であれば、

  * User A, Comment A
  * User A, Comment B
  * User A, Comment C
  * User B, Comment D
  * User B, Comment E
  * User C, (null)

といった結果を得られます。ここで重要なのは、JOINで結合されたテーブル（Comments）のデータはエンティティクラスに変換されません。また、重複を取り除く操作も指定しない限り行われません。

* * *

`contain` はCakePHP特有のメソッドです。  
これはアソシエーションの設定によって値の取得方法が変わります。

belongsTo, hasOneの親と子が1対1となる関係では、JOINによってテーブルが結合され値が取得されます。  
hasMany, belongsToManyの1対多、多対多の関係では親テーブルの取得を実行した後に、子テーブルから親に紐付くデータを別クエリで取得します。

例）上記のテーブルデータであれば、

  * User A 
    * Comment A
    * Comment B
    * Comment C
  * User B 
    * Comment D
    * Comment E
  * User C

のような形でデータを得られます。

* * *

なお、`hasMany` には、joinTypeというオプションはありません。似たようなオプションで `strategy` というオプションがあり、
`select` または `subquery` が選べます。

[アソシエーション - モデル同士を繋ぐ -
3.9](https://book.cakephp.org/3/ja/orm/associations.html#belongstomany)


CC BY-SA 4.0
2021-01-06T03:31:39.857
73114
2021-01-06T03:31:39.857
2668
73046
answer