使用ORM有什么好处?

作为一个网站开发者,希望从手工编码的PHP站点转移到基于框架的站点,我已经看到了很多关于一个ORM优于另一个的优点。 对于某些(?)规模的项目来说,这似乎是有用的,对于企业级应用程序更为重要。

作为一个开发者,它给了我什么? 我的代码如何与我现在使用的单个SELECT语句不同? 它将如何帮助数据库访问和安全性? 它如何发现数据库模式和用户凭证?

编辑: @duffymo指出什么应该是明显的我:ORM只是有用的OOP代码。 我的代码不是OO,所以我没有遇到ORM解决的问题。

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

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

如果你的对象与其他对象没有任何1:1,1:m或m:n的关系,那么使用ORM没什么意义。

如果您有复杂的手动调整的SQL,那么使用ORM就没有多less意义了。

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

如果您有一个复杂的传统架构,无法重构,那么使用ORM就没有太多意义。

所以这里是相反的:

如果您有一个坚实的对象模型,并且具有1:1,1:m和m:n的对象之间的关系,则不需要存储过程,就像ORM解决scheme通过一切方式向您提供的dynamicSQL使用ORM。

像这样的决定总是一个select。 select,实施,测量,评估。

数据访问问题的解决scheme正在炒作ORM。 就个人而言,在企业项目中使用它们之后,它们远不是企业应用程序开发的解决scheme。 也许他们在小型项目中工作。 以下是我们与他们经历的具体问题:nHibernate:

  1. configuration:ORM技术需要configuration文件将表模式映射到对象结构。 在大型企业系统中,configuration增长非常快,变得非常难以创build和pipe理。 随着业务需求和模型在敏捷的环境中不断变化和演变,维护configuration也变得单调乏味,难以维护。

  2. 自定义查询:映射不适合任何已定义对象的自定义查询的function要么不被支持,要么不被框架提供者推荐。 开发人员被迫通过编写adhoc对象和查询来find解决方法,或者编写自定义代码来获取他们需要的数据。 他们可能必须定期使用存储过程来执行比简单select更为复杂的任何操作。

  3. 企业绑定:这些框架要求使用专有库和专有对象查询语言,这些语言在计算机科学行业中是不标准的。 这些专有的库和查询语言将应用程序绑定到提供程序的特定实现上,几乎没有或没有灵活性来根据需要进行更改,并且没有互操作性来相互协作。

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

  5. 性能:ORM层使用reflection和内省来用数据库中的数据实例化和填充对象。 这些在处理方面是昂贵的操作,并增加了映射操作的性能下降。 对象查询被翻译为产生未优化的查询,而没有select调整它们导致显着的性能损失和数据库pipe理系统的过载。 性能调优SQL几乎是不可能的,因为框架对控制获取自动生成的SQL几乎没有灵活性。

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

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

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

在很高的层次上:ORM有助于减less对象关系阻抗不匹配。 它们允许您从关系数据库中存储和检索完整的活动对象,而无需自己进行大量的parsing/序列化。

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

对于初学者来说,它可以帮助你保持干爽。 无论是你的模式或模型类是权威的,而另一个是自动生成的,这减less了错误和锅炉板代码的数量。

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

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

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

它将如何帮助数据库访问和安全性?

一般来说,ORM具有自己的API来构build查询(如属性访问),所以不易受SQL注入攻击的影响; 但是,他们经常允许您将自己的SQL注入到生成的查询中,以便在需要时可以做出奇怪的事情。 这样注入的SQL你负责自己的消毒,但是,如果你远离使用这些function,那么ORM应该自动处理用户数据。

它如何发现数据库模式和用户凭证?

许多ORM提供了检查模式的工具,并build立了一组模型类,允许您与数据库中的对象进行交互。 [数据库]用户凭据通常存储在设置文件中。

如果您手动编写数据访问层,则基本上是编写自己的function较差的ORM。

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

编辑:OP在其他答案评论说,他的代码库不是很面向对象。 处理对象映射只是ORM的一个方面。 活动logging模式就是一个很好的例子,说明在对象映射1:1到表的情况下,ORM是如何有用的。

我不能说其他的ORM,只是Hibernate(用于Java)。

hibernate给了我以下几点:

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

您可以对数据库进行反向工程来创buildhibernate模式(我自己也没有尝试过),也可以从头开始创build模式。

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

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

主要优点:

  1. 数据库抽象
  2. 以API为中心的devise思路
  3. 高层次==不用担心在基础层面(它为你考虑)

我不得不说,与ORM合作实际上是数据库驱动应用程序的发展。 你不用担心你总是写的样板化的SQL,更多的是关于这些接口如何协同工作来构build一个非常简单的系统。

我喜欢不用担心INNER JOIN和SELECT COUNT(*)。 我只是在高层抽象工作,并且同时关心数据库抽象。

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

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

我build议你看一下正在使用的一些ORM,我最喜欢的是Python框架django中使用的ORM。 这个想法是,你写了一个数据在数据库中的外观定义,ORM负责validation,检查和插入数据之前需要运行的所有机制。

就个人而言,我还没有很好的使用ORM技术的经验。 我目前正在为一家使用nHibernate的公司工作,我真的无法继续。 给我一个存储过程和DAL任何一天! 更多的代码肯定…但也更多的控制和代码,更容易debugging – 从我的经验使用早期版本的nHibernate它必须被添加。

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

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

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

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

它将如何帮助数据库访问和安全性?

大多数框架都试图在适用的情况下遵循数据库最佳实践,例如参数化SQL等。 由于实现细节在框架中编码,所以您不必担心。 因此,理解你所使用的框架也是很重要的,并且要注意任何devise缺陷或者错误,这些错误或者错误可能会造成意想不到的漏洞。

它如何发现数据库模式和用户凭证?

您一如既往地提供连接string。 框架提供者(例如SQL,Oracle,MySQL特定类)提供查询数据库模式的实现,处理类映射,并根据需要呈现/执行数据库访问代码。

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

ORM的工作方式有两种:一种是从现有的数据库中发现模式–LINQToSQLdevise器是这样做的,另一些则需要你将类映射到一个表上。 在这两种情况下,一旦模式被映射,ORM可以为你创build(重新创build)你的数据库结构。 数据库权限可能仍然需要手动或通过自定义SQL应用。

通常,通过API以编程方式提供凭证,或者使用configuration文件(或两者)来提供凭证,这些凭证来自configuration文件,但可以在代码中覆盖。

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

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

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

…那么你可能会受益于一个轻量级的ORM,在这个ORM中,SQL不会被模糊或者抽象到更容易编写你自己的数据库集成的地步。

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

周围有许多开源的替代品可以完成类似的事情, jORM是我们提出的解决scheme。

我会build议在select一个轻量级的ORM之前评估一些最强的候选人。 他们在抽象数据库的方法上略有不同,但从顶部向下看来可能看起来很相似。

  • JORM
  • ActiveJDBC
  • ORMLite

我对ORM框架的关注可能是对许多开发人员有吸引力的事情。

他们不需要关心在数据库层面发生的事情。 我们在应用程序的日常运行中遇到的大多数问题都与数据库问题有关。 我担心的是一个100%ORM的世界,人们不知道什么样的查询会触及数据库,或者如果他们这样做,他们不确定如何改变或优化它们。

{我知道这可能是一个矛盾的答案:)}