m_shige1979のときどきITブログ

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

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

https://github.com/mshige1979

cakephp3で複数データをインサート

データを登録する際

1件ずつ登録するか、一括で登録するか…

環境

CentOS7.x
php7.0.3
cakephp3.2.3

一括で登録

sample1

src/Shell/Sample1Shell.php

<?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() 
    {

        // サンプルデータ準備
        $postList = [
            [
                "title" => "aaa1",
                "body" => "hogehoge1",
                "created" => date("Y-m-d H:i:s", strtotime("now")),
                "modified" => date("Y-m-d H:i:s", strtotime("now")),
            ],
            [
                "title" => "aaa2",
                "body" => "hogehoge2",
                "created" => date("Y-m-d H:i:s", strtotime("now")),
                "modified" => date("Y-m-d H:i:s", strtotime("now")),
            ],
            [
                "title" => "aaa3",
                "body" => "hogehoge3",
                "created" => date("Y-m-d H:i:s", strtotime("now")),
                "modified" => date("Y-m-d H:i:s", strtotime("now")),
            ],
        ];

        // テーブルオブジェクトを取得
        $posts = TableRegistry::get("Posts");
        // クエリーオブジェクトを取得
        $oQuery = $posts->query();

        // 配列単位にデータを設定
        foreach($postList as $post){
            // 1行ずつ設定
            $oQuery
                ->insert(['title', 'body', 'created', 'modified']) // キーを指定
                ->values($post);    // 明細を設定
        }

        // 実行
        $oQuery->execute();
    }
}

※モデルのsaveではないのでcreatedやmodifiedは任意で設定する必要があります。

SQL
INSERT INTO posts (
  title, body, created, modified
) VALUES 
 ('aaa1', 'hogehoge1', '2016-03-08 13:08:31', '2016-03-08 13:08:31'), 
  ('aaa2', 'hogehoge2', '2016-03-08 13:08:31', '2016-03-08 13:08:31'), 
  ('aaa3', 'hogehoge3', '2016-03-08 13:08:31', '2016-03-08 13:08:31')

一括で実行されています

一件ずつ登録

sample2

src/Shell/Sample2Shell.php

<?php
namespace App\Shell;

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

/**
 * Sample2 shell command.
 */
class Sample2Shell extends Shell
{

    /**
     * main() method.
     *
     * @return bool|int Success or error code.
     */
    public function main() 
    {
        // サンプルデータ準備
        $postList = [
            [
                "title" => "bbb1",
                "body" => "foofoo1",
            ],
            [
                "title" => "bbb2",
                "body" => "foofoo2",
            ],
            [
                "title" => "bbb3",
                "body" => "foofoo3",
            ],
        ];

        // テーブルオブジェクトを取得
        $posts = TableRegistry::get("Posts");

        // データを設定して複数のエンティティを取得
        $postsEntities = $posts->newEntities($postList);

        // データ数分保存する
        foreach($postsEntities as $entity){
            // 保存
            $posts->save($entity, ['atomic' => false]);
        }
    }
}

※createdなどは自動設定してくれる

SQL
INSERT INTO posts (title, body, created, modified) VALUES ('bbb1', 'foofoo1', '2016-03-08 13:23:24', '2016-03-08 13:23:24')
INSERT INTO posts (title, body, created, modified) VALUES ('bbb2', 'foofoo2', '2016-03-08 13:23:24', '2016-03-08 13:23:24')
INSERT INTO posts (title, body, created, modified) VALUES ('bbb3', 'foofoo3', '2016-03-08 13:23:24', '2016-03-08 13:23:24')

一件ずつ実行

所感

一括で登録できた方が楽なのでそちらを使う事になると思われる。変なデータになっていないかは別の方法でチェックして対応する
ビジネスロジックの場所に困りそうな状況になりつつあるけどまあ最初はコントローラーを困らせていこう(^ ^)