对于我开发的一些应用程序(后来渐渐忘记了),我一直在编写纯SQL,主要用于MySQL。虽然我在python中使用过orm,比如SQLAlchemy,但我并没有坚持使用它们太久。通常是文档或复杂性(从我的角度来看)阻碍了我。

我是这样认为的:为了可移植性,使用ORM,如果只使用一种类型的数据库,则使用纯SQL。在开发需要数据库支持的应用程序时,我真的在寻找关于何时使用ORM或SQL的建议。

考虑到这一点,使用轻量级包装器来处理数据库不一致要比使用ORM好得多。


当前回答

作为一个经常使用JPA (Java Persistence API,基本上是Java/J2EE/EJB的标准化ORM API)(包括Hibernate、EclipseLink、Toplink、OpenJPA等)的人,我将分享一些我的观察结果。

ORMs are not fast. They can be adequate and most of the time adequate is OK but in a high-volume low-latency environment they're a no-no; In general purpose programming languages like Java and C# you need an awful lot of magic to make them work (eg load-time weaving in Java, instrumentation, etc); When using an ORM, rather than getting further from SQL (which seems to be the intent), you'll be amazed how much time you spend tweaking XML and/or annotations/attributes to get your ORM to generate performant SQL; For complex queries, there really is no substitute. Like in JPA there are some queries that simply aren't possible that are in raw SQL and when you have to use raw SQL in JPA it's not pretty (C#/.Net at least has dynamic types--var--which is a lot nicer than an Object array); There are an awful lot of "gotchas" when using ORMs. This includes unintended or unexpected behavior, the fact that you have to build in the capability to do SQL updates to your database (by using refresh() in JPA or similar methods because JPA by default caches everything so it won't catch a direct database update--running direct SQL updates is a common production support activity); The object-relational mismatch is always going to cause problems. With any such problem there is a tradeoff between complexity and completeness of the abstraction. At times I felt JPA went too far and hit a real law of diminishing returns where the complexity hit wasn't justified by the abstraction.

还有一个问题需要更多的解释。

Web应用程序的传统模型是有一个持久层和一个表示层(中间可能有一个服务或其他层,但这是本文中重要的两个层)。orm强制从持久层到表示层(即实体)使用刚性视图。

对更原始SQL方法的批评之一是,您最终会得到所有这些仅由一个查询使用的vo(值对象)或dto(数据传输对象)。这被吹捧为orm的一个优势,因为你摆脱了这一点。

问题是,这些问题不会随着orm而消失,它们只会上升到表示层。不为查询创建VOs/ dto,而是创建自定义表示对象,通常为每个视图创建一个。这怎么更好呢?恕我直言,它不是。

我已经用ORM或SQL写过了:我们做到了吗?

最近我选择的持久化技术(在Java中)是ibatis。它是一个非常薄的SQL包装器,可以完成JPA所能做的90%以上的工作(它甚至可以进行惰性加载关系,尽管它没有良好的文档),但开销要小得多(就复杂性和实际代码而言)。

这是在去年我编写的GWT应用程序中出现的。在服务实现中,从EclipseLink到表示对象的大量转换。如果我们使用ibatis,那么用ibatis创建适当的对象,然后在堆栈中上下传递它们就会简单得多。一些纯粹主义者可能会认为这是坏的™。也许是这样(理论上),但我告诉你:它会带来更简单的代码、更简单的堆栈和更高的生产力。

其他回答

在现代软件开发场景中,是否使用框架是非常常见的难题。

重要的是要理解每个框架或方法都有其优点和缺点——例如,根据我们的经验,我们发现ORM在处理事务时很有用,即插入/更新/删除操作——但当涉及到获取具有复杂结果的数据时,评估ORM工具的性能和有效性就变得重要了。

同样重要的是要理解,选择一个框架或方法并在其中实现所有内容并不是强制性的。我们的意思是,我们可以混合使用ORM和本地查询语言。许多ORM框架在本地SQL中为插件提供扩展点。我们应该尽量不要过度使用一个框架或方法。我们可以结合某些框架或方法,得出适当的解决方案。

当涉及到高并发性的插入、更新、删除和版本控制时,可以使用ORM,还可以使用Native SQL生成报告和长清单

ORMs have some nice features. They can handle much of the dog-work of copying database columns to object fields. They usually handle converting the language's date and time types to the appropriate database type. They generally handle one-to-many relationships pretty elegantly as well by instantiating nested objects. I've found if you design your database with the strengths and weaknesses of the ORM in mind, it saves a lot of work in getting data in and out of the database. (You'll want to know how it handles polymorphism and many-to-many relationships if you need to map those. It's these two domains that provide most of the 'impedance mismatch' that makes some call ORM the 'vietnam of computer science'.)

对于事务性应用程序,即您发出请求,获取一些对象,遍历它们以获得一些数据并在Web页面上呈现,性能损失很小,并且在许多情况下ORM可以更快,因为它将缓存以前见过的对象,否则将多次查询数据库。

对于报告量大的应用程序,或者每个请求都要处理大量的数据库行,ORM税要重得多,它们所做的缓存变成了一个巨大的、无用的内存占用负担。在这种情况下,可以使用简单的SQL映射(LinQ或iBatis)或在瘦DAL中手工编写SQL查询。

我发现,对于任何大型应用程序,您都会发现自己同时使用这两种方法。(ORM用于直接的CRUD, SQL/thin DAL用于报告)。

我想和大家一起回答:“我们有一个中间立场!”

对于应用程序程序员来说,SQL是您可能想要控制的东西和您几乎肯定不想费心控制的东西的混合体。

我一直想要的是一个层(称之为DAL、ORM或microorm,我不介意哪个),它将负责完全可预测的决策(如何拼写SQL关键字,括号放在哪里,何时创建列别名,为一个包含两个浮点数和一个int的类创建哪些列……),同时让我负责SQL的高级方面,即如何安排join、服务器端计算、DISTINCTs、GROUP by、标量子查询等。

所以我写了一些这样的东西:http://quince-lib.com/

这是针对c++的:我不知道这是否是你正在使用的语言,但同样的,看看这个“中间地带”的样子可能会很有趣。

没有“一刀切”的解决方案,对于“我是否应该使用an或/m”这个问题也是如此。”。

我会说:如果你必须写一个非常“数据”的应用程序/工具,没有太多的其他逻辑,那么我会使用纯SQL,因为SQL是这类应用程序的领域特定语言。

另一方面,如果我要编写一个包含大量“领域”逻辑的业务/企业应用程序,那么我将编写一个富类模型,它可以在代码中表达这个领域。在这种情况下,OR/M映射器可能会非常有用,因为它可以从您手中省去大量管道代码。

我知道这个问题很老了,但我想我应该在这里发布一个答案,以防有人像我一样遇到这个问题。orm已经走过了很长的路。其中一些实际上为您提供了两全其美的服务:提高开发效率并保持性能。

看看SQL Data (http://sqldata.codeplex.com)。它是c#的一个轻量级ORM,涵盖了所有基础。

供参考,我是SQL数据的作者。