ang3 / doctrine-orm-batch-process
Doctrine ORM 批处理组件
Requires
- php: >=8.1
- doctrine/orm: ^2.12
Requires (Dev)
- symfony/test-pack: ^1.0
README
此组件帮助您在 Doctrine ORM 事务的上下文中处理 批处理。
批量操作的主要问题通常不是耗尽内存,这正是这里提出的策略提供的帮助。 -- Doctrine ORM 文档
批处理组件允许您使用一些高级特性轻松构建批量操作。
安装
打开命令行控制台,进入您的项目目录,并执行以下命令以下载此捆绑包的最新稳定版本
$ composer require ang3/doctrine-orm-batch-process
此命令需要您全局安装了 Composer,具体请参阅 Composer 文档中的安装章节。
使用方法
批处理是一个使用 迭代器 执行一些逻辑的 循环,其中 处理器 是可选的。迭代器是强制性的,处理器是可选的。
在所有情况下,当缓冲区大小达到(默认为20)时,实体管理器都会被刷新和清除。
创建一个过程
要创建一个过程,使用带有实体管理器和迭代器的构造函数,或者使用定义的静态快捷方法之一来满足您的需求
use Ang3\Doctrine\ORM\Batch\BatchProcess; $myProcess = new BatchProcess($entityManager, $myIterator, $myHandler = null, $bufferSize = 20); // For chaining calls $myProcess = BatchProcess::create($entityManager, $myIterator); /* * SHORTCUT METHODS FOR BUILT-IN ITERATORS */ // Iterate from identified entities $myProcess = BatchProcess::iterateEntities($entityManager, $entityFqcn, array $identifiers); // Iterate from an ORM query or query builder instance $myProcess = BatchProcess::iterateQueryResult($query); // Iterate from iterable or callable $myProcess = BatchProcess::iterateData($entityManager, iterable|\Closure $data);
执行过程
$nbIterations = $myProcess->execute();
高级选项
此组件提供了一些有用的高级选项。
处理器
处理器是一个实现了接口 Ang3\Doctrine\ORM\Batch\Handler\BatchHandlerInterface
的类。这个类在每次迭代时被调用。它允许您持久化/删除实体,或者使用自定义处理器执行任何操作。
此接口描述了批处理过程调用的方法:__invoke(\Ang3\Doctrine\ORM\Batch\BatchIteration $iteration)
。
该组件提供了一些有用的内置处理器。
持久化实体处理器
此处理器将实体持久化到数据库中。
use Ang3\Doctrine\ORM\Batch\Handler\PersistEntityHandler; $myHandler = PersistEntityHandler::new() // Handler options... ->skipInsertions() // Ignore new entities (without ID) ->skipUpdates() // Ignore stored entities (with ID) ->onPrePersist($myCallable) // This callable is called BEFORE each persist. ->onPostPersist($myCallable) // This callable is called AFTER each persist. ;
可调用参数
object
实体Ang3\Doctrine\ORM\Batch\BatchIteration
迭代
删除实体处理器
此处理器将实体从数据库中删除。
use Ang3\Doctrine\ORM\Batch\Handler\RemoveEntityHandler; $myHandler = RemoveEntityHandler::new() // Handler options... ->onPreRemove($myCallable) // This callable is called BEFORE each removing. ->onPostRemove($myCallable) // This callable is called AFTER each removing. ;
可调用参数
object
实体Ang3\Doctrine\ORM\Batch\BatchIteration
迭代
可调用处理器
此处理器包含一个简单的可调用对象。
use Ang3\Doctrine\ORM\Batch\Handler\CallableHandler; $myHandler = CallableHandler::new($myCallable);
可调用参数
mixed
迭代器数据Ang3\Doctrine\ORM\Batch\BatchIteration
迭代
链式处理器
此处理器允许您按特定顺序链式调用处理器。
use Ang3\Doctrine\ORM\Batch\Handler\ChainHandler; $myHandler = ChainHandler::new() // Handler options... ->append($myHandler1) // Add a handler at the end of the chain ->prepend($myHandler2) // Add a handler at the beginning of the chain ->clear() // Remove all handlers from the chain ;
自定义处理器
创建一个实现接口 Ang3\Doctrine\ORM\Batch\Handler\BatchHandlerInterface
的类。
namespace App\Doctrine\Batch\Handler; use Ang3\Doctrine\ORM\Batch\Handler\BatchHandlerInterface; final class MyHandler implements BatchHandlerInterface { public function __invoke(Iteration $iteration): void { // Data from the process iterator $data = $iteration->getData(); // You can retrieve the entity manager from the iteration. $em = $iteration->getEntityManager(); } }
使用 Ang3\Doctrine\ORM\Batch\Handler\BatchHandlerTrait
特性来启用选项
// ... final class MyHandler implements BatchHandlerInterface { // If you want to add options: use BatchHandlerTrait; // Internal constants used to define options private const OPTION_ENABLED = 'enabled'; public function __invoke(Iteration $iteration): void { // Retrieves option values $enabled = $this->getOption(self::OPTION_ENABLED); // your logic with the option... } // Return the handler to allow chaining calls public function enableOption(bool $enabled = true): self { $this->setOption(self::OPTION_ENABLED, $enabled); return $this; } }
缓冲区大小
您可以修改默认的缓冲区大小
$myProcess->setBufferSize(50); // By default: 20
禁用 ID 生成器
您可以关闭一个或多个实体的 ID 生成器,这对于迁移数据很有用。
$myProcess->disableIdGenerator(MyClass1::class, MyClass2::class/*, ...*/);
您可以恢复以下禁用的 ID 生成器
$myProcess->restoreIdGenerator(MyClass1::class, MyClass2::class/*, ...*/); // ... Or restore all directly $myProcess->restoreAllIdGenerators();
事务实体
实体管理器可能会多次被清除。这就是为什么在执行过程中,所有在执行前加载的实体都将从管理器中分离。
$myLoadedEntity; // attached $myProcess->execute(); dump($myLoadedEntity); // Probably detached - If you persist, a new entity could be created!
为了避免重新加载您的实体,此组件可以帮助您通过 变量引用 将实体保持在内存中,以便自动重新加载它。
$myLoadedEntity; // attached $myProcess ->addTransactionalEntity($myLoadedEntity) // This variable is passed by reference ->execute(); dump($myLoadedEntity); // reloaded by the process on each flush/clear
在刷新时
您可以将一个可调用对象传递给批处理,以便在每次刷新/清除操作上执行一些逻辑。
$myProcess->onFlush($myCallable);
可调用参数
Ang3\Doctrine\ORM\Batch\BatchProcess
当前批处理Ang3\Doctrine\ORM\Batch\BatchIteration|null
迭代(在最后刷新/清空时为NULL)。