使用ORM有什么好处?

时间:2008-12-29 17:14:30

标签: orm

作为一名希望从手工编写的PHP站点迁移到基于框架的站点的Web开发人员,我已经看到了很多关于一个ORM优于另一个ORM的优势的讨论。它似乎对某些(?)大小的项目很有用,对企业级应用程序更为重要。

作为开发者,它给了我什么?我的代码与我现在使用的各个SELECT语句有何不同?它如何帮助数据库访问和安全性?它如何找到有关数据库架构和用户凭据的信息?

编辑: @duffymo指出应该对我来说显而易见的事情:ORM仅对OOP代码有用。我的代码不是OO,所以我没有遇到ORM解决的问题。

13 个答案:

答案 0 :(得分:86)

我会说,如果你不处理对象,那么使用ORM就没什么意义了。

如果关系表/列使用对象/属性映射1:1,则使用ORM没有多大意义。

如果您的对象与其他对象没有任何1:1,1:m或m:n关系,则使用ORM没有多大意义。

如果你有复杂的,手动调整的SQL,使用ORM没有多大意义。

如果您已确定您的数据库将存储过程作为其接口,则使用ORM没有多大意义。

如果您有一个无法重构的复杂遗留架构,那么使用ORM没有多大意义。

所以这是相反的:

如果你有一个实体对象模型,对象之间的关系是1:1,1:m和m:n,那么就没有存储过程,就像ORM解决方案给你的动态SQL一样,一定要使用ORM。

这些决定始终是一种选择。选择,实施,衡量,评估。

答案 1 :(得分:39)

ORM正在被大肆宣传为数据访问问题的解决方案。就个人而言,在企业项目中使用它们之后,它们远远不是企业应用程序开发的解决方案。也许他们在小项目中工作。以下是我们遇到的问题,特别是nHibernate:

  1. 配置:ORM技术需要配置文件将表模式映射到对象结构中。在大型企业系统中,配置增长非常快,并且变得极难创建和管理。随着业务需求和模型在敏捷环境中不断变化和发展,维护配置也变得乏味且难以维护。

  2. 自定义查询:框架提供程序不支持或不推荐映射不适合任何已定义对象的自定义查询的功能。开发人员不得不通过编写adhoc对象和查询,或编写自定义代码来获取所需的数据来找到解决方法。他们可能不得不定期使用存储过程来处理比简单选择更复杂的事情。

  3. 契约绑定:这些框架需要使用专有的库和专有对象查询语言,这些语言在计算机科学行业中并未标准化。这些专有库和查询语言将应用程序绑定到提供程序的特定实现,在需要时很少或根本没有灵活性进行更改,并且没有相互协作的互操作性。

  4. 对象查询语言:提供称为对象查询语言的新查询语言,以对对象模型执行查询。它们会自动生成针对数据库的SQL查询,并从流程中抽象出用户。对于面向对象的开发人员来说,这似乎是一个好处,因为他们觉得编写SQL的问题已经解决了。实际问题是这些查询语言不能支持大多数现实世界应用程序所需的一些中高级SQL结构。它们还可以防止开发人员在必要时调整SQL查询。

  5. 性能:ORM层使用反射和内省来使用数据库中的数据实例化和填充对象。这些在处理方面是昂贵的操作并且增加了映射操作的性能降级。对象查询被转换为生成未优化的查询,而无需调整它们,从而导致显着的性能损失和数据库管理系统的过载。性能调优SQL几乎是不可能的,因为框架在控制自动生成的SQL方面提供的灵活性很小。

  6. 紧耦合:这种方法在模型对象和数据库模式之间产生了严格的依赖关系。开发人员不希望数据库字段和类字段之间存在一对一的关联。更改数据库模式会在对象模型和映射配置中产生波动影响,反之亦然。

  7. 缓存:此方法还需要使用对象缓存和上下文,这些对象缓存和上下文是维护和跟踪对象状态所必需的,并减少缓存数据的数据库往返。如果不在多层实现中维护和同步,这些高速缓存可能在数据准确性和并发性方面产生重大影响。通常需要插入第三方缓存或外部缓存来解决此问题,从而给数据访问层增加了大量负担。

  8. 有关我们分析的更多信息,您可以阅读: http://www.orasissoftware.com/driver.aspx?topic=whitepaper

答案 2 :(得分:33)

处于非常高的水平:ORM有助于减少对象关系阻抗不匹配。它们允许您从关系数据库中存储和检索完整的活动对象,而无需自己进行大量的解析/序列化。

  

作为开发者,它给了我什么?

对于初学者来说,它可以帮助你保持干爽。您可以使用模式或模型类是权威的,另一个是自动生成的,这样可以减少错误的数量和样板代码的数量。

它有助于编组。 ORM通常将单个列的值编组到适当的类型中,这样您就不必自己解析/序列化它们。此外,它允许您从数据库中检索完全形成的对象,而不是简单地排列您必须包装自己的对象。

  

我的代码与我现在使用的各个SELECT语句有何不同?

由于您的查询将返回对象而不是行,因此您将能够使用属性访问而不是创建新查询来访问相关对象。您通常可以在需要时直接编写SQL,但对于大多数操作(CRUD),ORM将使与持久对象交互的代码更简单。

  

如何帮助进行数据库访问和安全性?

一般来说,ORM有自己的API来构建查询(例如属性访问),因此不易受SQL注入攻击的影响;但是,它们通常允许您将自己的SQL注入生成的查询中,以便在需要时可以执行奇怪的操作。这样注入的SQL你负责清理自己,但是,如果你不使用这些功能,那么ORM应该自动处理用户数据的清理。

  

如何了解数据库架构和用户凭据?

许多ORM都带有工具,可以检查模式并构建一组模型类,允许您与数据库中的对象进行交互。 [数据库]用户凭据通常存储在设置文件中。

答案 3 :(得分:14)

如果您手动编写数据访问层,那么您实际上是在编写自己的功能很差的ORM。

Oren Eini有一个很好的博客,总结了你在DAL / ORM中可能需要的基本功能,以及为什么写下你自己的功能在一段时间后成为一个坏主意: http://ayende.com/Blog/archive/2006/05/12/25ReasonsNotToWriteYourOwnObjectRelationalMapper.aspx

编辑:OP在其他答案中评论说他的代码库不是非常面向对象的。处理对象映射只是ORM的一个方面。 Active Record模式是ORM如何在对象将1:1映射到表的情况下仍然有用的一个很好的例子。

答案 4 :(得分:8)

主要好处:

  1. 数据库抽象
  2. 以API为中心的设计心态
  3. 高等级==少担心基础(被认为适合你)
  4. 我不得不说,使用ORM实际上是数据库驱动的应用程序的演变。您不必担心您总是编写的样板SQL,更多关于接口如何协同工作以构建一个非常简单的系统。

    我不必担心INNER JOIN和SELECT COUNT(*)。我只是在高级抽象中工作,同时我也在处理数据库抽象。

    话虽如此,我从来没有真正遇到过这样一个问题:我需要在多个数据库系统上一次运行相同的代码。但是,这并不是说案例不存在,对于一些开发者来说这是一个非常现实的问题。

答案 5 :(得分:8)

我不能代表其他ORM,只是Hibernate(对于Java)。

Hibernate给了我以下内容:

  • 在运行时自动更新生产系统上的表的架构。有时你仍然需要自己手动更新一些东西。
  • 自动创建外键,使您无法编写创建孤立数据的错误代码。
  • 实现连接池。可以使用多个连接池提供程序。
  • 缓存数据以加快访问速度。可以使用多个缓存提供程序。这也允许您将许多服务器聚集在一起,以帮助您扩展。
  • 使数据库访问更加透明,以便您可以轻松地将应用程序移植到另一个数据库。
  • 使查询更容易编写。通常要求您三次写入“join”的以下查询可以这样写:
    • “来自Invoice i,其中i.customer.address.city =?”这将检索具有特定城市的所有发票
    • 返回Invoice对象列表。然后我可以调用invoice.getCustomer()。getCompanyName();如果数据不在缓存中,则在后台自动查询数据库

您可以对数据库进行反向工程以创建hibernate架构(我自己没有尝试过),或者您可以从头开始创建架构。

当然,学习曲线与任何新技术一样,但我认为这是值得的。

如果需要,您仍然可以下拉到较低的SQL级别来编写优化查询。

答案 6 :(得分:6)

大多数使用的数据库都是关系数据库,不直接转换为对象。对象关系映射器所做的是获取数据,使用实用程序函数在其周围创建一个shell,以便更新,删除,插入和执行其他操作。因此,不要将其视为行数组,而是现在有一个objets列表,您可以像操作任何其他对象一样操作,只需在完成后调用obj.Save()。

我建议你看一下正在使用的一些ORM,我最喜欢的是python框架中使用的ORM,django。我们的想法是编写数据在数据库中的外观定义,ORM负责验证,检查以及在插入数据之前需要运行的任何机制。

答案 7 :(得分:5)

就我个人而言,迄今为止我还没有使用过ORM技术的丰富经验。我目前正在为一家使用nHibernate的公司工作,我真的无法继续使用它。随时给我一个存储过程和DAL!更多代码确定......但更多的控件和代码更容易调试 - 根据我使用早期版本的nHibernate的经验,它必须添加。

答案 8 :(得分:4)

  

作为开发者,它给了我什么?

节省您的时间,因为您不必编写数据库访问部分的代码。

  

我的代码与我现在使用的各个SELECT语句有何不同?

您将使用属性或xml文件来定义到数据库表的类映射。

  

如何帮助进行数据库访问和安全性?

大多数框架都尝试在适用的情况下遵循db最佳实践,例如参数化SQL等。因为实现细节是在框架中编码的,所以您不必担心它。因此,理解您正在使用的框架并了解任何可能导致意外漏洞的设计缺陷或错误也很重要。

  

如何找到有关数据库架构和用户凭据的信息?

您始终提供连接字符串。框架提供程序(例如SQL,Oracle,MySQL特定类)提供查询db模式,处理类映射以及根据需要呈现/执行db访问代码的实现。

答案 9 :(得分:4)

使用ORM将删除代码对特定SQL方言的依赖关系。您将与一个抽象层进行交互,而不是直接与数据库交互,该抽象层在您的代码和数据库实现之间提供绝缘。此外,ORM通常通过构造参数化查询来提供对SQL注入的保护。你可以自己做,但是保证框架保证很好。

ORM以两种方式之一工作:一些从现有数据库中发现模式 - LINQToSQL设计者执行此操作 - 其他人则要求您将类映射到表中。在这两种情况下,一旦映射了模式,ORM就可以为您创建(重新创建)数据库结构。数据库权限可能仍需要手动或通过自定义SQL应用。

通常,凭据通过API或使用配置文件以编程方式提供凭据 - 或者两者都是默认值来自配置文件,但能够在代码中覆盖。

答案 10 :(得分:4)

有关详细讨论ORM的播客,请参阅以下链接。 http://se-radio.net/podcast/2008-12/episode-121-or-mappers-michael-ploed

答案 11 :(得分:1)

虽然我几乎完全同意接受的答案,但我认为可以考虑使用轻量级替代品进行修改。

  • 如果您有复杂的,手动调整的SQL
  • 如果您的对象与其他对象没有任何1:1,1:m或m:n关系
  • 如果您有一个无法重构的复杂遗留架构
  

...那么你可能会从轻量级ORM中受益,其中SQL不是   模糊或抽象到更容易编写你的   自己的数据库集成。

这些是我公司的开发团队决定我们需要更灵活的抽象来驻留在JDBC之上的众多原因中的一小部分。

有许多开源替代品可以实现类似的功能,jORM是我们提出的解决方案。

我建议在选择轻量级ORM之前评估一些最强的候选者。它们在抽象数据库方法上略有不同,但从俯视图看起来可能类似。

答案 12 :(得分:0)

我对ORM框架的关注可能是让很多开发人员感兴趣的东西。

但是,它不需要“关心”数据库级别的内容。我们在应用程序的日常运行中看到的大多数问题都与数据库问题有关。我稍微担心一个100%ORM的世界,人们不会知道什么查询会影响数据库,或者如果他们这样做,他们不确定如何更改或优化它们。

{我意识到这可能是一个反对的答案:)}