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

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

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


当前回答

使用像SQL一样工作的ORM,但提供编译时检查和类型安全。比如我最喜欢的:数据知识对象(披露:是我写的)

例如:

for (Bug bug : Bug.ALL.limit(100)) {
  int id = bug.getId();
  String title = bug.getTitle();
  System.out.println(id +" "+ title);
}

完全流。易于设置(不需要定义映射-读取现有模式)。支持连接、事务、内部查询、聚合等。几乎可以用SQL做任何事情。从庞大的数据集(金融时间序列)一直到琐碎的数据集(Android),这一点都得到了证明。

其他回答

作为一个经常使用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路由不是最快的。但是,当您拥有一个中型到大型的团队时,DB正在迅速变化,从DB中重新生成类和映射作为构建过程的一部分的能力是值得注意的,特别是当您使用CI时。所以你的代码可能不是最快的,但你的代码会-我知道我在大多数项目中会采用哪种。

我的建议是在模式仍处于流动状态时使用ORM进行开发,使用分析来发现瓶颈,然后使用原始Sql优化那些需要它的区域。

另一个想法是,如果使用得当,Hibernate内建的缓存通常可以大大提高性能。不再需要返回DB读取引用数据。

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

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

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

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

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

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

任何值得尊敬的设计都需要对数据库进行一些抽象,以处理阻抗不匹配。但是我认为最简单的第一步(对于大多数情况来说已经足够了)应该是DAL,而不是重量级的ORM。你唯一的选择并不是那些极端的选择。


编辑回复一个要求我描述如何区分DAL和ORM的评论:

DAL是您自己编写的,可能从简单地封装一个表并将其字段映射到属性的类开始。ORM是不需要为从dbms模式的其他属性推断出的抽象机制而编写的代码,主要是pk和fk。(这是您发现自动抽象是否开始出现漏洞的地方。我更喜欢有意地告知他们,但这可能只是我的个人偏好)。