PHP ORM:Doctrine vs. Propel

Posted

技术标签:

【中文标题】PHP ORM:Doctrine vs. Propel【英文标题】:PHP ORMs: Doctrine vs. Propel 【发布时间】:2011-01-04 23:17:00 【问题描述】:

我正在使用symfony 开始一个新项目,该项目很容易与Doctrine 和Propel 集成,但我当然需要做出选择....我想知道是否有更多有经验的人有使用这两者的一般优点和/或缺点?

非常感谢。

编辑: 感谢所有回复,有用的东西。这个问题没有真正正确的答案,所以我只会将获得最多票数的答案标记为已批准。

【问题讨论】:

各位,有更新的回复吗?看到这种方式已经过时了 【参考方案1】:

我会选择 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。

【讨论】:

在 Propel 1.5 中,这个查询也可以写成 Example_Query::create()->joinWith('FooBar')->filterId(20)->find() (或 findPK(20)如果 Id 是您的主键,则在 joinWith 之后)。如您所见,它采用了 Doctrine 的漂亮语法,并添加了更多内容。该版本计划在 2010 年第一季度末发布,但您现在可以在您的 Symfony 项目中对其进行测试。 不错的输入,我不知道 :-) 学说的实现对我来说似乎要复杂得多。获取实体管理获取存储库......这个和那个 学说已经使事情复杂化了......只是 notorm 是要走的路【参考方案2】:

我有偏见,因为我对 Propel 的下一个版本提供了一些帮助,但你必须考虑到 Propel 确实是第一个可用的 ORM,然后在 Doctrine 创建时有点滞后,但现在又开始积极开发了。 Symfony 1.3/1.4 带有 Propel 1.4,大多数比较都停留在 Propel 1.3。此外,Propel (1.5) 的下一个版本将包含许多改进,尤其是在创建 Criteria 方面(导致您编写的代码更少)。

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

也许您还应该考虑适用于不同框架的 Symfony 插件的可用性。我相信 Propel 在这里有优势,但我不知道列出的插件中有多少仍然与最新版本的 Symfony 保持同步。

【讨论】:

Propel 1.5 中新的查询改进确实很棒。【参考方案3】:

这取决于个人喜好。 我使用 Propel 是因为(除其他外)我喜欢一切都有自己的具体 getter 和 setter 方法的事实。在 Doctrine 中,情况并非如此。

推进:

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

教义:

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

我喜欢 getter 和 setter 的原因是,如果需要,我可以在其中放入各种逻辑。但这只是我个人的喜好。

我还应该补充一点,虽然 Propel 过去发展缓慢,但它现在再次处于积极开发中。在过去的几个月里,它发布了几个新版本。最新版本的 Propel 包含类似于 Doctrine 的“流畅查询界面”,因此如果您不想再使用 Criteria,则不必再使用。

【讨论】:

在 Doctrine 中,您可以覆盖每个属性的 setter 和 getter,并且还具有自定义逻辑(请参阅 doctrine-project.org/documentation/manual/1_2/en/… - 搜索 ATTR_AUTO_ACCESSOR_OVERRIDE 以进入相关部分) 看起来没问题,但是您仍然可以通过调用来设置属性: $x->propname = 'abc';这是有问题的,因为它似乎不支持传递多个参数。【参考方案4】:

应该注意Doctrine 2 目前正在开发中 released [ed] 并且功能几乎与当前稳定版本的 Doctrine 1 完全不同。它依赖在 Data Mapper 模式而不是 Active Record 上,并使用“实体管理器”来处理持久性逻辑。发布后,它将与 Java 的 Hibernate 更相似(Doctrine 1 更像 Rails 的 ActiveRecord)。

我一直在使用 Doctrine 2 的 alpha 版本进行开发,并且必须说它比 Doctrine 1 高出许多(只是我的看法,我从未使用过 Propel)。 Doctrine 社区很有可能会在它发布时朝着它前进。

我鼓励你查看 Doctrine,但如果你更喜欢 Propel 和 Doctrine 现在使用的 Active Record 风格,你可能只想坚持使用 Propel。

【讨论】:

最近发布了 Doctrine 2 的稳定版本。 doctrine-project.org/blog/doctrine2-released【参考方案5】:

这两个参考文献有些过时,因此您仍然涵盖了一些一般性,基本上您必须评估您对框架的体验,学说的一个主要缺点是无法拥有一个允许您自动编码的 IDE如果你的项目需要管理复杂的数据模型使用原则,如果你想快速使用文档最好的 ORM 并找到更多在 Propel Internet 使用方面的支持,更加成熟,我相信是最常用的。

http://propel.posterous.com/propel-141-is-out

【讨论】:

在 symfony 世界中,Doctrine 似乎无疑是最常用的——尤其是对于较新的项目。当然还有很多 sf 1.0 项目仍然使用 Propel,因为 Doctrine 直到 1.1 才可用于 symfony。【参考方案6】:

我建议使用 propel 1.6,它更适合 IDE 的自动完成功能。

【讨论】:

-1 IDE 的自动完成不应成为技术选择的原因 @ClementHerreman 我同意这不应该是标准,但我相信使用特定技术的生产力应该是a选择它的理由。因此,恕我直言,我不同意您的反对意见……无论您是否同意答案,这都不是“错误”(或者是吗?),并且它是有用的(除非它是错误的,在这种情况下,你应该说明这一点)。 IMO 如果您的生产力是通过自动完成而不是软件质量、直观性和一致性来提高的,那么奇怪的事情正在发生。见codinghorror.com/blog/2009/01/…。但你是对的,在某些时候这个答案并没有错误,只是不够好,甚至可能还不够好。 @ClementHerreman,如果没有帮助,请不要再使用它;),+1 对此有最新的回应吗?这已经过时了。【参考方案7】:

我不是 PHP 5 非框架 ORM 的用户,但这里有一些很好的比较帖子(如果你还没有看过的话):

http://codeutopia.net/blog/2009/05/16/doctrine-vs-propel-2009-update/

http://trac.symfony-project.org/wiki/ComparingPropelAndDoctrine

这两个结论都喜欢 Doctrine 作为 Symfony 的新一代 ORM。

【讨论】:

作为记录,这种比较已经完全过时了——当前版本的 Propel 确实使用 PDO,确实支持多对多关系,并且有很好的文档。同样值得考虑的是:我们中的一些人更喜欢冗长的标准构建器查询样式,而不是像 DQL 这样的专有查询语言——它具有 IDE 支持,并且它是一个类,因此您可以对其进行扩展。我仍在尝试选择,但是如果您不介意静态代码生成并且可以看到“真实” PHP 代码相对于专有查询语言的优势,我看到 Propel over Doctrine 有很多优点,这只是 IDE 的字符串。【参考方案8】:

在使用它们多年后,我更喜欢 Propel 2 而不是 Doctrine,这只是基于您构建查询逻辑的方式。教义尽可能深入,并且管理它的许多方面都与该深度水平相匹配。 Propel 我觉得有一种更流畅和对象驱动的方式来构建和管理查询交互。

对我来说,这导致模型中的代码更少,并且围绕如何处理逻辑的结构更多。这导致只是将许多交互构建为通用功能。 (毕竟 90% 的数据库操作都只是某种程度的杂乱无章的操作。)

最终,两者都功能强大、易于管理并且可以完成工作。我的个人项目和兴趣使用 Propel ORM 2 和未来的项目,如果仍然用 PHP 编写将走这条路。

在过去的 3-4 年里,我每天都在使用这两种方法。

【讨论】:

【参考方案9】:

我建议使用DbFinder Plugin。这实际上是一个非常强大的插件,它支持两者,并且非常强大。我实际上比任何一个都更喜欢使用它。

【讨论】:

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

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

【讨论】:

以上是关于PHP ORM:Doctrine vs. Propel的主要内容,如果未能解决你的问题,请参考以下文章

从 orm.xml Doctrine 生成 php 实体

使用 PHP Doctrine ORM 的复杂 WHERE 子句

将 Codeigniter 2 与 Doctrine ORM 2 < PHP v5.2 一起使用

Doctrine 2.2 ORM:查找扩展实体

Symfony2 Doctrine ORM 安装配置

使用 Doctrine orm symfony 创建新数据库时出错