LoginSignup
0
1

More than 1 year has passed since last update.

day14の今日は、複数のデータを一気に更新するバッチ更新のやり方を見ていきます。

Doctrine

<?php

declare(strict_types=1);

use App\Entity\Author;
use App\Entity\Book;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\ResultSetMapping;

require __DIR__.'/../vendor/autoload.php';

/** @var EntityManagerInterface $entityManager */
$entityManager = require __DIR__.'/bootstrap.php';

// エンティティを使ってやる
for ($i = 1; $i <= 100; $i++) {
    $book = new Book();
    $book->setTitle(sprintf('title%d', $i));
    $book->setPrice(100 * $i);
    $entityManager->persist($book);
}
$entityManager->flush(); // begin + 100件のinsert + commitがここで行われる

// エンティティを使えないぐらい多い件数を扱う場合
$conn = $entityManager->getConnection();
$conn->beginTransaction();
for ($i = 1; $i <= 1000000; $i++) {
    $conn->insert('books', [
        'title' => sprintf('title%d', $i),
        'price' => $i * 10,
    ]);
}
$conn->commit();

// updateもできる
$conn->beginTransaction();
for ($i = 1; $i <= 1000000; $i++) {
    $conn->update('books', [
        'price' => $i * 20,
    ], ['id' => $i]);
}
$conn->commit();

https://github.com/77web/doctrine-vs-eloquent/blob/702e4b4c597f5afb043ad5d2d26b21ad44addf4e/Doctrine/Usecase/batch_insert_update.php

  • 通常のエンティティを用いた保存でもflush()を呼ぶまでinsertやupdateは発行されないので、バッチ更新的になる。
  • エンティティはPHPのオブジェクトなので、大量にインスタンスを作るとPHPのメモリを消費しすぎる。それを避けるためにEntityManagerから getConnection() を使ってconnectionを取り出してinsert, updateを行うこともできる。(EntityManager::getConnection()の返り値は Doctrine\DBAL\Connection

Eloquent

<?php

declare(strict_types=1);

use App\Models\Book;
use Illuminate\Support\Facades\DB;

require __DIR__.'/../vendor/autoload.php';
require __DIR__.'/bootstrap.php';

// insert
DB::beginTransaction();
for ($i = 1; $i <= 100000; $i++) {
    Book::query()->insert(['title' => sprintf('title%d', $i), 'price' => $i * 100]);
}
DB::commit();

// update
DB::beginTransaction();
for ($i = 1; $i <= 100000; $i++) {
    DB::update(
        'UPDATE books SET title = ?, price = ? WHERE id = ?',
        [
            sprintf('title%d', $i),
            $i * 200,
            $i,
        ]
    );
}
DB::commit();

https://github.com/77web/doctrine-vs-eloquent/blob/702e4b4c597f5afb043ad5d2d26b21ad44addf4e/Eloquent/Usecase/batch_insert_update.php

  • モデルを用いてバッチinsert, バッチupdateをするにはサードパーティパッケージが必要
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1