对于我开发的某些应用程序(后来逐渐忘记了),我一直在编写纯SQL,主要是针对MySQL。尽管我在SQLAlchemy之类的python中使用过ORM ,但是我并没有坚持很长时间。通常这是文档或复杂性(从我的角度来看)使我退缩。
我这样看:如果要使用一种数据库,则使用ORM进行可移植性,使用普通SQL。我真的在寻求有关在开发需要数据库支持的应用程序时何时使用ORM或SQL的建议。
考虑一下,与使用ORM相比,仅使用轻量级包装器来处理数据库不一致会更好。
对于我开发的某些应用程序(后来逐渐忘记了),我一直在编写纯SQL,主要是针对MySQL。尽管我在SQLAlchemy之类的python中使用过ORM ,但是我并没有坚持很长时间。通常这是文档或复杂性(从我的角度来看)使我退缩。
我这样看:如果要使用一种数据库,则使用ORM进行可移植性,使用普通SQL。我真的在寻求有关在开发需要数据库支持的应用程序时何时使用ORM或SQL的建议。
考虑一下,与使用ORM相比,仅使用轻量级包装器来处理数据库不一致会更好。
Answers:
ORM具有一些不错的功能。他们可以处理将数据库列复制到对象字段的繁琐工作。他们通常负责将语言的日期和时间类型转换为适当的数据库类型。它们通常还可以通过实例化嵌套对象来优雅地处理一对多关系。我发现如果您在设计数据库时考虑了ORM的优点和缺点,那么在将数据移入或移出数据库时可以节省很多工作。(如果需要映射它们,您将想知道它如何处理多态性和多对多关系。正是这两个域提供了大多数“阻抗不匹配”,这使得有些人将ORM称为“计算机科学的越南”。 )
对于事务性应用程序,即您发出请求,获取一些对象,遍历它们以获取一些数据并将其呈现在网页上,性能负担很小,在许多情况下,ORM可以更快,因为它将缓存对象,如前所述,否则将多次查询数据库。
对于报表繁重的应用程序,或每个请求要处理大量数据库行的应用程序,ORM负担要重得多,并且它们所做的缓存会变成很大的无用的内存消耗负担。在这种情况下,精简DAL中的简单SQL映射(LinQ或iBatis)或手工编码的SQL查询就是解决之道。
对于任何大型应用程序,我都发现您会同时使用这两种方法。(ORM用于简单的CRUD,而SQL / thin DAL用于报告)。
以花很多时间使用JPA(Java持久性API,基本上是Java / J2EE / EJB的标准化ORM API)的人(包括Hibernate,EclipseLink,Toplink,OpenJPA等)发言,我将分享一些我的知识。观察。
还有另一个问题需要更多解释。
Web应用程序的传统模型是具有一个持久层和一个表示层(可能在它们之间有一个服务或其他层,但这是本次讨论的重要两层)。ORM强制从您的持久性层到表示层(即您的实体)的僵化视图。
对更多原始SQL方法的批评之一是,您最终只能使用一个查询使用所有这些VO(值对象)或DTO(数据传输对象)。吹捧这是ORM的优势,因为您摆脱了这一点。
问题是,ORM并不会解决这些问题,它们只会上升到表示层。您无需创建查询的VO / DTO,而是创建自定义的表示对象,通常为每个视图一个。这样更好吗 恕我直言,事实并非如此。
最近,我选择的(在Java中)持久性技术是ibatis。它是围绕SQL的一个非常薄的包装程序,可以完成JPA可以完成的90%以上的工作(尽管它没有详细记录,它甚至可以进行关系的延迟加载),但开销却少得多(就复杂性和实际代码而言)。
这是去年在我正在编写的GWT应用程序中出现的。从EclipseLink到服务实现中的表示对象的大量转换。如果我们使用ibatis,那么使用ibatis创建合适的对象然后将它们一直沿堆栈上下传递要简单得多。一些纯粹主义者可能会认为这是Bad™。也许是这样(理论上),但是我告诉你什么:它可以导致更简单的代码,更简单的堆栈和更高的生产率。
我说普通的SQL代表R eads,ORM代表CUD。
性能是我一直关注的问题,尤其是在Web应用程序中,同时也是代码的可维护性和可读性。为了解决这些问题,我写了SqlBuilder。
ORM不仅是可移植性(就此而言,即使使用ORM也很难实现)。当ORM工具使您免于编写样板化的SQL查询(通过PK或谓词,插入,更新和删除进行选择)并使您专注于问题域时,它为您提供的基本上是持久性存储上的抽象层。
任何合理的设计都需要对数据库进行某种抽象,以处理阻抗不匹配的问题。但是我希望最简单的第一步(对于大多数情况而言是足够的)将是DAL,而不是重量级的ORM。您唯一的选择不是在频谱的末端。
编辑以回应要求我描述我如何区分DAL和ORM的评论:
DAL是您自己编写的,也许是从只封装表并将其字段映射到属性的类开始的。ORM是您不编写的代码,也不是从dbms模式的其他属性(主要是PK和FK)推断出的抽象机制。(在这里您可以找到自动抽象是否开始泄漏。我宁愿有意地通知他们,但这可能只是我个人的喜好)。
每个工具都有其目的和愿景。我创建了http://www.jooq.org/正是为了满足您的需求,尽管iBatis可能也是您的理想选择。
jOOQ具有基本的ORM功能,但主要集中于我想大多数开发人员在尝试找到最适合他们需求的ORM时最需要的功能:
但是通常它们走得太远,提供了太多的抽象,您不会认为它们正在针对RDBMS运行。另一方面,您选择RDBMS正是因为
jOOQ正好解决了这些问题。它的性能将与JDBC一样好,但没有痛苦。
在现代软件开发方案中,是否使用框架的难题非常普遍。
需要理解的重要一点是,每种框架或方法都有其优缺点-例如,根据我们的经验,我们发现ORM在处理事务(即插入/更新/删除操作)时很有用-但是在处理复杂的数据时结果,评估ORM工具的性能和有效性变得很重要。
同样重要的是要了解选择一个框架或方法并实施其中的所有内容不是强制性的。我们的意思是说,我们可以混合使用ORM和本机查询语言。许多ORM框架在本机SQL中为插件提供了扩展点。我们应该尽量不要过度使用框架或方法。我们可以结合某些框架或方法,并提供适当的解决方案。
在涉及高并发性的插入,更新,删除,版本控制时,您可以使用ORM,并且可以使用Native SQL来生成报告和详细列出清单。
使我的ORM真正发挥作用的关键是代码生成。我同意,就代码性能而言,ORM路由并不是最快的。但是,当您拥有中型到大型团队时,数据库正在迅速变化,在构建过程中,从数据库重新生成类和映射的能力令人眼前一亮,尤其是当您使用CI时。因此,您的代码可能不是最快的,但是您的代码将是-我知道我将在大多数项目中采用哪种代码。
我的建议是在Schema仍然运行时使用ORM进行开发,使用性能分析来查找瓶颈,然后使用原始Sql调整那些需要它的区域。
另一个想法是,如果使用正确的方式,内置在Hibernate中的缓存通常可以大大提高性能。无需再回到数据库读取参考数据了。
没有“一刀切”的解决方案,对于“我是否应该使用or / m?'。
我会说:如果您必须编写一个非常注重“数据”的应用程序/工具,而没有太多其他逻辑,那么我将使用普通SQL,因为SQL是此类应用程序的领域特定语言。
另一方面,如果我要编写一个包含很多“域”逻辑的业务/企业应用程序,那么我将编写一个丰富的类模型,该模型可以用代码表达该域。在这种情况下,OR / M映射器可能对成功完成操作非常有帮助,因为它需要大量的管道代码。
我开发的应用程序之一是用python编写的IRC机器人。它使用的模块在单独的线程中运行,但我还没有找到使用sqlite时处理线程的方法。不过,对于一个单独的问题可能会更好。
我真的应该只改写标题和实际问题。我以前从未真正使用过任何语言的DAL。
使用与 SQL 相似但提供编译时检查和类型安全性的ORM 。就像我最喜欢的:数据知识对象(公开:我写的)
例如:
for (Bug bug : Bug.ALL.limit(100)) {
int id = bug.getId();
String title = bug.getTitle();
System.out.println(id +" "+ title);
}
完全流式传输。易于设置(无需定义映射-读取现有架构)。支持联接,事务,内部查询,聚合等。您几乎可以在SQL中执行任何操作。并且已经从巨型数据集(财务时间序列)一直到微不足道(Android)进行了证明。
我知道这个问题很老,但是我认为我会发布答案,以防有人遇到像我这样的人。ORM已经走了很长一段路。实际上,其中一些功能可以为您提供两全其美的优势:提高开发效率和保持性能。
看一下SQL数据(http://sqldata.codeplex.com)。这是一个非常轻巧的c#ORM,涵盖了所有基础。
仅供参考,我是SQL Data的作者。
我想在回答“有一个中间立场!”的答复中加入我的声音。
对于应用程序程序员而言,SQL是您可能要控制的事物和几乎肯定不希望控制的事物的混合体。
我一直想要的是一个层(称为DAL,ORM或微型ORM,我不介意哪一个),它将负责完全可预测的决策(如何拼写SQL关键字,括号的位置,何时发明列别名,为包含两个浮点数和一个int的类创建什么列...),同时让我负责SQL的高级方面,即如何安排JOIN,服务器端计算, DISTINCT,GROUP BY,标量子查询等。
所以我写了一些做这件事的东西:http : //quince-lib.com/
它是针对C ++的:我不知道您是否使用的是这种语言,但是同样的,看到这种“中间立场”可能是有趣的。