2012-07-14 67 views
17

在使用学说时,我注意到要删除一个实体,我需要通过给定的参数(名称,ID等)来检索该实体,然后调用remove方法。另一方面,在查询中,我可以执行删除查询。学说实体删除vs删除查询,性能比较

所以,好像,使用ORM风格需要两个操作和一般的sql操作需要一个操作。这就是为什么,我有点困惑,我们是否应该在ORM中使用删除(或更新)操作?性能不好吗?还是还有什么我失踪? ORM风格可以以其他方式完成吗?

回答

38

在Doctrine2中,您可以调用未从数据库加载的代理对象上的删除。只要创建一个“虚拟”的对象,像:

$user = $em->getPartialReference('model\User', array('id' => $id)); 
$em->remove($user); 

它不需要初始查询,但我不肯定是否主义仍然没有在内部上fush。我没有在SqlLog中看到它。

只是补充一点,我认为这是任何体面的ORM的预期行为。它处理对象和关系。在删除它之前,它必须知道有某种东西存在。 ORM不仅仅是一个查询生成器。通常,任何ORM中的本机查询总是会更快。任何ORM都会添加一个抽象层,并且需要一些时间来执行它。这是一个典型的权衡,你会得到一些奇特的功能和干净的代码,但是在性能上会有一些松动。

编辑:

我很高兴它的工作适合你。其实我偶然发现了另一个问题,这让我意识到代理和部分对象实际上并不是一回事。部分对象将实例模型类实例化,并用您想要的值填充它。在你初始化一个局部对象之后,懒加载不再适用它了。因此,例如,如果仅使用id创建部分对象,并且只想在另一个对象字段满足某些条件时删除它,则它将不起作用,因为该其他字段将始终为空。

另一方面,代理可以使用延迟加载,并且不会共享部分对象所具有的问题。所以我强烈建议不要使用getPartialReference方法,而不是你可以这样做:如果不是

$user = $em->getReference('model\User', $id); 
$em->remove($user); 

getReference方法返回如果已经装好或对象的代理。代理可以在需要时延迟加载所有其他值。至于你的例子,他们会表现完全一样,但代理无疑是更好的方法。

+1

谢谢你的信息和澄清 – Rana 2012-07-15 06:23:29

4

完成! 对我来说,它的工作原理是这样的第3行:

$user = $em->getReference('model\User', $id); 
$em->remove($user); 
$em->flush();