ocramius/doctrine-batch-utils

一组用于操作 Doctrine ORM 批处理功能的工具

2.8.0 2024-07-10 09:25 UTC

README

此存储库旨在简化在 Doctrine ORM 事务环境中处理 批处理 的难度。

此存储库由 Patrick Reimers (PReimers) 维护。

License Current release Build Status

安装

支持的安装方法是使用 Composer

composer require ocramius/doctrine-batch-utils

当前功能

目前,此存储库中唯一实现的实用工具是一个包装 DB 事务并调用给定 EntityManager 上的 ObjectManager#flush()ObjectManager#clear()IteratorAggregate

示例(数组迭代)

它可以按以下方式使用

use DoctrineBatchUtils\BatchProcessing\SimpleBatchIteratorAggregate;

$object1  = $entityManager->find('Foo', 1);
$object2  = $entityManager->find('Bar', 2);

$iterable = SimpleBatchIteratorAggregate::fromArrayResult(
    [$object1, $object2], // items to iterate
    $entityManager,       // the entity manager to operate on
    100                   // items to traverse before flushing/clearing
);

foreach ($iterable as $record) {
    // operate on records here
}

$record 新鲜度

请注意,循环中的 $record 总是“新鲜”的(托管 状态),因为迭代器会自行重新获取它:这可以防止您在每次迭代中手动调用 ObjectManager#find()

自动刷新/清除

在此示例中,EntityManager 只会刷新和清除一次,但如果记录数超过 100,则可能会刷新(并清除)两次或更多。

示例(查询/迭代器)

上一个示例仍然不是内存效率高的,因为我们正在操作 ORM 预加载的对象数组。

我们可以使用查询代替

use DoctrineBatchUtils\BatchProcessing\SimpleBatchIteratorAggregate;

$iterable = SimpleBatchIteratorAggregate::fromQuery(
    $entityManager->createQuery('SELECT f FROM Files f'),
    100 // flush/clear after 100 iterations
);

foreach ($iterable as $record) {
    // operate on records here
}

或我们自己的迭代器/生成器

use DoctrineBatchUtils\BatchProcessing\SimpleBatchIteratorAggregate;

// This is where you'd persist/create/load your entities (a lot of them!)
$results = function () {
    for ($i = 0; $i < 100000000; $i += 1) {
        yield new MyEntity($i); // note: identifier must exist in the DB
    }
};
 
$iterable = SimpleBatchIteratorAggregate::fromTraversableResult(
    $results(),
    $entityManager,
    100 // flush/clear after 100 iterations
);

foreach ($iterable as $record) {
    // operate on records here
}

// eventually after all records have been processed, the assembled transaction will be committed to the database

这两种方法都更内存高效。