我正在开发一个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] 删除。
我来说两句