adawolfa/batchtrine

用于 Doctrine ORM 的简化批处理垃圾回收器。

1.0.1 2024-04-21 16:27 UTC

This package is auto-updated.

Last update: 2024-09-03 16:28:07 UTC


README

用于 Doctrine ORM 的简化批处理垃圾回收器。

安装

composer require adawolfa/batchtrine

使用

垃圾回收器通过在每次批处理开始时复制工作单元的单位映射,并在之后选择性地分离所有之前未包含在内的实体来工作。这些实体通常不应在批处理作用域之外使用。

这旨在解决 EntityManager::clear() 的问题,它使应用中所有对实体的现有引用无效,并且手动分离实体要简单得多。

单批次

batch() 方法运行提供的回调,转发其返回值,并在其执行期间分离所有加载或创建的实体。

$gc = new Adawolfa\Batchtrine\GC($em);

$a = $em->getRepository(Entity::class)->findBy(['code' => 'a']);

$b = $gc->batch(function () use ($em): Entity {
	return $em->getRepository(Entity::class)->findBy(['code' => 'b']);
});

$em->contains($a); // true
$em->contains($b); // false - entity is detached

迭代器

iterate() 方法返回一个代理迭代器,它会在设定次数的迭代($interval)后执行垃圾回收周期。

$a = $em->getRepository(Entity::class)->findBy(['code' => 'a']);

foreach ($gc->iterate($ids) as $id) {
	$entity = $em->getRepository(Entity::class)->find($id);
	assert($a !== $entity);
	// ...
}

$em->contains($a);      // true
$em->contains($entity); // false

分页

paginate() 方法对于遍历大型 Doctrine\ORM\Query 结果集非常有用。结果是通过重复执行查询以较小的限制($interval)和增加偏移量来获取的。垃圾回收周期发生在获取新结果页之前。

$a = $em->getRepository(Entity::class)->findBy(['code' => 'a']);

$query = $em->createQueryBuilder()
	->select('e')
	->from(Entity::class, 'e')
	->getQuery();

foreach ($gc->paginate($query) as $entity) {
	assert($a !== $entity);
	// ...
}

$em->contains($a);      // true
$em->contains($entity); // false

对于经常变化的数据,应使用搜索后方法。

$query = $em->createQueryBuilder()
	->select('e')
	->from(Entity::class, 'e')
	->where('e.id > :id')
	->orderBy('e.id')
	->getQuery();

$after = function (Query $query, ?Entity $last): void {
	$query->setParameter('id', $last?->id ?? 0);
};

foreach ($gc->paginate($query, after: $after) as $entity) {
	assert($a !== $entity);
	// ...
}