在Symfony / Doctrine中删除大量用户数据的最佳/禁食解决方案

安德烈·赫福德

我正在开发一个Symfony 2.8允许注册用户管理联系人、文档、约会等的项目。

现在我想实现一个功能,允许用户重置/删除他们的所有数据。因此,用户帐户本身应保持不变,但应删除所有数据实体。

目前我正在使用Doctrine/ORM方法来遍历所有实体并删除它们:

public function deleteAllData($user) {
    $this->currentBatch = 0;
    $this->deleteEntities('MyBundle:Contact', $user);
    $this->deleteEntities('MyBundle:Document', $user);
    ...
    $this->deleteEntities('MyBundle:...', $user);

    $this->flushIfNecessary(true);
}

private function deleteEntities($type, $user) {
   $repo = $this->em->getRepository($type);
   $entities = $repo->findByUser($user);

   foreach ($entities as $entity) {
       $repo->delete($entity);
       $this->flushIfNecessary();
   }
}

private function flushIfNecessary($force = false) {
    $this->currentBatch++;

    if ($force || $this->currentBatch % 100 == 0) {
        $this->em->flush();
        $this->em->clear();
    }
}

虽然这工作正常,但速度很慢使用不同的批量大小,我能够稍微加快这个过程,但是删除大量条目仍然需要很长时间。当然,这是由于ORM在后台完成的所有处理。

使用简单SQL查询会快得多

private function deleteEntities($type, $user) {
   $tableName = null;
   $userId = $user->getId();

   switch ($type) {
       case 'MyBundle:Document':
           $tableName = 'document';
           break;
       ...
   }

   if ($tableName && $userId) {
       $this->em->getConnection()->query("
           DELETE FROM $tableName 
           WHERE user_id = '$userId'
       ");
   }
}

该解决方案也有效,但它需要知道内部数据库结构,例如不同实体的表名、userId字段名称等。

当然,获取这些信息没什么大不了的,但对我来说,这个解决方案似乎不像第一个解决方案那么干净。

有没有办法Doctrine在仍然正常查询/绕过的同时获取必要的信息ORM

或者有没有更好的解决方案来完成这项工作?

杰库查罗维奇

由于对象水合作用,您的第一种方法很慢您实际上并不需要加载所有记录并将它们转换为对象。您可以简单地使用QueryBuilder

$qb = $em->createQueryBuilder('c');
$qb->delete('MyBundle:Contact', 'c')
   ->where('c.user = :user')
   ->setParameter('user', $user)
   ->getQuery()
   ->execute()
;

或者DQL

$query = $em->createQuery(
              'DELETE MyBundle:Contact c 
               WHERE c.user = :user')
            ->setParameter('user', $user);
$query->execute();

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章