PHP ORM:Doctrine vs Propel

127
我正在使用symfony开始一个新项目,它可以轻松集成DoctrinePropel,但我当然需要做出选择...我想知道更有经验的人对选择这两个中的任何一个有哪些优缺点?
非常感谢。
编辑: 感谢所有回复,很有用的信息。对于这个问题没有真正正确的答案,所以我将批准得到最多赞成票的答案。

7
各位,有更新的回复吗?看起来这个已经过时了。 - Qiniso
10个回答

78

我会选择Doctrine。在我看来,它是一个更加活跃的项目,并且作为symfony的默认ORM,得到了更好的支持(即使正式地认为这些ORM是平等的)。

此外,我更喜欢使用查询的方式(DQL而不是Criteria):

<?php
// Propel
$c = new Criteria();
$c->add(ExamplePeer::ID, 20);
$items = ExamplePeer::doSelectJoinFoobar($c);

// Doctrine
$items = Doctrine_Query::create()
       ->from('Example e')
       ->leftJoin('e.Foobar')
       ->where('e.id = ?', 20)
       ->execute();
?>

(对我来说,Doctrine的实现方式更加直观易懂。)

而且,我真的更喜欢Doctrine中关系的处理方式。

我认为Doctrine文档中的这个页面值得一读: http://www.doctrine-project.org/documentation/manual/1_2/en/introduction:doctrine-explained

总之,如果我要开始一个新项目或必须在学习Doctrine和Propel之间做出选择,我会毫不犹豫地选择Doctrine。


42
在 Propel 1.5 中,这个查询也可以这样写:Example_Query::create()->joinWith('FooBar')->filterId(20)->find()(如果ID是您的主键,则在joinWith之后使用findPK(20))。正如您所看到的,它继承了Doctrine的优雅语法,并增加了更多功能。该版本计划于2010年Q1末发布,但您现在可以在您的Symfony项目中进行测试。 - Jan Fabry
不错的输入,我不知道 :-) - phidah
9
实施教义对我来说似乎更加复杂。获取实体管理器,获取存储库......等等。 - SoWhat
1
Doctrine过于复杂化了... NotORM才是正确的选择。 - Geomorillo

39

我有点偏袒Propel,因为我在下一个版本的开发中提供了一些帮助,但你必须考虑到Propel确实是第一个可用的ORM,后来Doctrine问世后有点落后,但现在又重新活跃起来了。Symfony 1.3 / 1.4 内置Propel 1.4,大部分比较都停留在 Propel 1.3。而且,下一个版本的Propel(1.5)将包含很多改进,特别是在创建查询标准方面(这将使您需要编写的代码更少)。

我喜欢Propel,因为它似乎比Doctrine更简单:大部分代码都在少数生成的类中,而Doctrine则将功能拆分到许多类中。我喜欢对我正在使用的库有一个很好的理解(不要太多“魔法”),但当然,我对Propel有更多的经验,所以也许Doctrine在幕后并不那么复杂。一些人说Propel更快,但你应该自己测试并考虑这是否超过其他差异。

也许你还应该考虑不同框架的Symfony插件的可用性。我认为Propel在这方面有优势,但我不知道列出的插件有多少与最新版本的Symfony兼容。


4
Propel 1.5 中的新查询改进确实非常好。 - Tom

23

这取决于个人偏好。我使用 Propel,因为(除了其他原因)我喜欢每个东西都有自己的具体 getter 和 setter 方法。在 Doctrine 中并非如此。

Propel:

$person->setName('Derek');
echo $person->getName();

Doctrine:

$person->name = 'Derek';
echo $person->name;

我喜欢使用getter和setter的原因是,如果需要的话,我可以在它们中加入各种逻辑。不过这只是我的个人偏好。

另外,我还应该补充一点,即使Propel过去发展缓慢,但现在它又在积极地开发中。过去几个月里,它已经发布了几个新版本。最近的Propel版本包含了一个类似于Doctrine的“流畅查询接口”,所以如果你不想使用Criteria,也可以使用它。


7
在Doctrine中,您可以覆盖每个属性的setter和getter,并且还可以编写自定义逻辑(请参见 http://www.doctrine-project.org/documentation/manual/1_2/en/introduction-to-models - 搜索 ATTR_AUTO_ACCESSOR_OVERRIDE 以获取相关部分)。 - Marek Karbarz
看起来还不错,但你仍然通过调用 $x->propname = 'abc'; 来设置属性。这是有问题的,因为它似乎不支持传递多个参数。 - lo_fye

20

需要注意的是,Doctrine 2已经发布[ed],并且与当前稳定版本的Doctrine 1在功能上基本完全不同。它采用数据映射器模式(Data Mapper pattern)而不是Active Record,并使用“实体管理器”(entity manager)来处理持久性逻辑。发布后,它将更接近于Java的Hibernate(Doctrine 1更像Rails的ActiveRecord)。

我已经使用Doctrine 2的alpha版进行开发,并且必须说它比Doctrine 1(这只是我的个人意见,我从未使用过Propel)要好得多。 Doctrine社区很可能在发布后向它靠拢。

我鼓励您尝试使用Doctrine,但如果您喜欢Propel和Doctrine现在使用的Active Record风格,那么您可能想坚持使用Propel。


4
最近发布了Doctrine 2的稳定版本。http://www.doctrine-project.org/blog/doctrine2-released - Trevor Allred

5
这两个参考资料有点过时,因此您仍然需要涵盖一些概括性内容。基本上,您需要评估您对该框架的经验; Doctrine的一个主要缺点是无法使用让您自动编码的IDE,而Propel则胜出。学习曲线在Propel和Doctrine之间非常不同,Propel更容易。如果您的项目需要管理复杂的数据模型,请使用Doctrine;如果您想要快速使用ORM,并且希望有最好的文档支持和在Propel Internet中找到更多支持,则使用Propel,它更加成熟,我相信使用最广泛。http://propel.posterous.com/propel-141-is-out

在Symfony的世界中,Doctrine似乎是最常用的ORM框架,特别是对于新项目而言。当然,仍有很多使用Propel的sf 1.0项目,因为Doctrine直到1.1版本才能在Symfony中使用。 - phidah

5

我建议使用 Propel 1.6,这对 IDE 的自动完成功能更好。


29
IDE的自动完成功能不应成为技术选择的原因。 - Clement Herreman
14
我同意它不应该是“唯一”的标准,但我相信使用特定技术能否提高工作效率肯定是选择它的“一个”原因。尽管如此恕我直言,我不同意你的反对票...无论你是否同意答案,它都不是“错误的”(或者说它确实是错误的吗?),它有一定的用处(除非它是错误的,在这种情况下,你应该指出来)。 - Sepster
2
如果你的生产力更多地依赖于自动完成而不是软件质量、直观性和一致性,那么可能出现了一些奇怪的情况。请参见http://www.codinghorror.com/blog/2009/01/the-sad-tragedy-of-micro-optimization-theater.html。但你说得对,在某个程度上,这个答案并没有错,只是不够好,甚至可能不好。 - Clement Herreman
1
@ClementHerreman,如果没有帮助,请不要再使用它了;),+1 - amd
有最新的回复吗?这太过陈旧了。 - Qiniso
显示剩余2条评论

2

1
值得一提的是,这个比较已经过时了 - Propel 的当前版本确实使用 PDO,并支持多对多关系,并且有很好的文档。还值得考虑的是:我们中的一些人更喜欢冗长的条件构建器查询风格,而不是像 DQL 这样的专有查询语言 - 它具有 IDE 支持,并且它是一个类,所以你可以扩展它。我仍在努力选择,但我看到 Propel 相对于 Doctrine 有很多优点,如果你不介意静态代码生成,并且能够看到“真正”的 PHP 代码相对于专有查询语言的优势,后者只是 IDE 中的字符串。 - mindplay.dk

2
使用这两个ORM框架多年后,我更喜欢Propel 2而不是Doctrine,主要是基于你如何构建查询逻辑。Doctrine可以深入到最深处,并管理许多方面匹配该深度级别。我认为Propel具有更流畅和面向对象的方式来构建和管理查询交互。对我来说,这导致模型中的代码较少,而围绕逻辑如何处理的结构更多。这就导致只需将许多交互作为常见功能构建即可。(毕竟,您将使用数据库的90%仅是某种程度的CRUD操作。)最终,两者都强大、可管理,并且能够完成工作。我个人的项目和兴趣使用Propel ORM 2,如果未来的项目仍然使用PHP编写,则会采用这种方法。我过去3-4年每天都在使用这两种框架。

1

我建议使用DbFinder插件。这实际上是一个非常强大的插件,支持两种方式,并且非常好用。我实际上比起其他两种更喜欢使用它。


@Mike:谢谢,我不知道这个插件,但似乎它只支持Sf1.2。最终我选择了Doctrine,感觉这是正确的选择,尽管对于更复杂的东西需要编写直接SQL。 - Tom

-2
如果我没记错的话,这两个ORM都使用基于XML的模式,创建这些模式定义相当麻烦。如果你需要一个基于PHP的简单模式和流畅的风格,可以尝试使用LazyRecord https://github.com/c9s/LazyRecord,它支持自动迁移和升级/降级脚本生成器。所有类文件都是静态生成的,没有运行时成本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接