首页 文章

有没有充分的理由不使用ORM? [关闭]

提问于
浏览
95

在我的学徒期间,我使用NHibernate进行了一些我自己编码和设计的较小项目 . 现在,在开始一个更大的项目之前,讨论产生了如何设计数据访问以及是否使用ORM层 . 由于我还在学徒中,并且仍然认为自己是企业编程的初学者,所以我并没有真正尝试推动我的观点,即使用对象关系映射器到数据库可以大大简化开发 . 开发团队中的其他程序员比我经验丰富,所以我想我会按照他们的说法去做 . :-)

但是,我并不完全理解不使用NHibernate或类似项目的两个主要原因:

  • 可以使用SQL查询构建自己的数据访问对象,并将这些查询复制出Microsoft SQL Server Management Studio .

  • 调试ORM可能很难 .

所以,当然我可以用很多 SELECT 等构建我的数据访问层,但是在这里我会错过自动连接,延迟加载代理类的优势以及如果表获得新列或列的较低维护工作量被重命名 . (更新了许多 SELECTINSERTUPDATE 查询与更新映射配置,并可能重构业务类和DTO . )

此外,如果您不熟悉框架,使用NHibernate可能会遇到无法预料的问题 . 例如,这可能是信任Table.hbm.xml,您可以在其中设置字符串的长度以自动验证 . 但是,我也可以想象一下基于“简单”SqlConnection查询的数据访问层中的类似错误 .

最后,上面提到的那些论点真的是一个很好的理由不将ORM用于基于数据库的非平凡企业应用程序吗?他/我可能错过了其他可能的争论吗?

(我应该补充一点,我认为这就像第一个基于.NET / C#的“大型”应用程序需要团队合作 . 在Stack Overflow上被认为非常正常的良好实践,例如单元测试或持续集成,都是非 - 到现在为止 . )

20 回答

  • 3

    我建议阅读这个阅读列表,列出ORM的缺点 .

    http://blogs.tedneward.com/2006/06/26/The+Vietnam+Of+Computer+Science.aspx

    对于我自己,我发现ORM对我编写的大多数应用程序非常有用!

    /导演Asger

  • 54

    近年来,随着ORM的增长迅速增长,您经验丰富的同事可能仍在思考“每个数据库调用都应该通过存储过程”的心态 .

    为什么ORM会使调试变得更难?无论是来自存储过程还是来自ORM,您都会得到相同的结果 .

    我想,我能用ORM想到的唯一真正的不利因素是安全模型的灵活性稍差 .

    EDIT: 我只是重新阅读了你的问题,看起来它们是复制并将查询粘贴到内联sql中 . 这使得安全模型与ORM相同,因此与ORM相比,这种方法绝对没有优势 . 如果他们使用的是非参数查询,则实际上存在安全风险 .

  • 6

    对于基于非平凡数据库的企业应用程序,没有理由不使用ORM .

    特色:

    • 如果不使用ORM,您将解决大型社区或拥有大量资源的公司已反复解决的问题 .

    • 通过使用ORM,数据访问层的核心部分受益于该社区或公司的调试工作 .

    为了在论证中加入一些观点,请考虑使用ADO.NET与编写代码来自行解析表格数据流的优势 .

    我已经看到无知如何使用ORM证明开发人员对ORM的蔑视例如:渴望加载(我注意到你没有提到的东西) . 想象一下,您想要检索客户及其所有订单,以及所有订单明细项目 . 如果您只依赖于延迟加载,那么您将从ORM体验中摒弃以下观点:“ORM很慢 . ”如果您学习如何使用预先加载,您将在2分钟内完成5行代码,您的同事将花费半天时间来实现:对数据库进行一次查询并将结果绑定到对象层次结构 . 另一个例子是手动编写SQL查询以实现分页的痛苦 .

    使用ORM的可能例外是,该应用程序是一个ORM框架,旨在应用专门的业务逻辑抽象,并设计为在多个项目上重用 . 但是,即使是这种情况,也可以通过使用这些抽象增强现有ORM来更快地采用 .

    不要让你的高级团队成员的经验把你拉向与计算机科学发展相反的方向 . 我一直在专业发展23年,其中一个常数就是老派对新人的蔑视 . ORM是SQL,因为C语言是汇编,你可以打赌C和C#的等价物正在路上 . 一行新学校代码相当于20行老派 .

  • 3

    我首先要说的是,如果正确集成,ORM可以使您的开发生活更轻松,但是有一些问题,ORM实际上可以阻止您实现您声明的要求和目标 .

    我发现在设计具有高性能要求的系统时,我经常会遇到挑战,想方设法使系统更高效 . 很多时候,我最终得到的解决方案具有较高的写入性能(这意味着我们写的数据比我们读取数据的要多得多) . 在这些情况下,我想利用数据库平台为我提供的设施来实现我们的性能目标(它是OLTP,而不是OLAP) . 因此,如果我使用的是SQL Server,并且我知道我要编写大量数据,为什么我不会使用批量插入...好吧,正如您可能已经发现的那样,大多数ORMS(我不知道是否甚至一个人也没有能力利用平台特定的优势,如批量插入 .

    您应该知道可以混合使用ORM和非ORM技术 . 我刚刚发现有一些边缘情况,ORM无法满足您的要求,您必须为这些情况解决这些问题 .

  • 3

    不是答案本身,我想改写一下我最近听到的一句话 . “一个好的ORM就像一个雪人,每个人都谈论一个,但没有人看到它 . ”

    每当我把手放在ORM上时,我通常会发现自己正在努力解决ORM的问题/限制 . 最后,是的,它做了我想要的,它写在那个糟糕的文档的某处,但我发现自己又失去了一个小时,我永远不会得到 . 任何使用nhibernate,然后在postgresql上使用流利的nhibernate的人都会明白我曾经历过的 . 不断感觉“这段代码不在我的控制之下”真的很糟糕 .

    我没有指责或说他们不好,但我开始考虑我只是为了在单个表达式中自动化CRUD而给予的东西 . 现在我认为我应该少用ORM,可能创建或找到一个能够最小化db操作的解决方案 . 但这只是我 . 我相信在这个ORM领域有些事情是错的,但是我没有足够的技巧来表达它没有 .

  • 8

    简短的回答是肯定的,有很好的理由 . 事实上,有些情况下您无法使用ORM .

    例如,我在一家大型企业金融机构工作,我们必须遵循许多安全准则 . 为了满足我们的规则和规定,通过审核的唯一方法是在存储过程中保持数据访问 . 现在有些人可能会说这只是愚蠢的,但说实话,事实并非如此 . 使用ORM工具意味着工具/开发人员可以插入,选择,更新或删除他或她想要的任何内容 . 存储过程提供了更高的安全性,尤其是在处理客户端数据时的环境中 . 我认为这是最重要的考虑因素 . 安全 .

  • 2

    我想也许当你在更大的系统上工作时,你可以使用CodeSmith等代码生成器工具而不是ORM ...我最近发现:Cooperator Framework生成SQL Server存储过程并生成业务实体,映射器,网关,lazyload C#中的所有内容......检查一下......它是由阿根廷的一个团队写的......

    我认为编码整个数据访问层和使用ORM之间的中间...

  • 45

    我认为使用ORM仍然是一个好主意 . 特别是考虑到你给出的情况 . 听起来你的帖子,你在数据库访问策略方面更有经验,我会提出使用ORM .

    对于#1没有争论,因为复制和粘贴查询并且文本中的硬编码没有灵活性,对于#2,大多数orm将包装原始异常,将允许跟踪生成的查询等,因此调试也不是火箭科学 .

    至于验证,在任何内置验证之上,使用ORM通常还可以更容易地开发验证策略 .

    编写自己的框架可能很费力,而且往往会错过任何事情 .

    编辑:我想再说一点 . 如果贵公司采用ORM策略,进一步提升其 Value ,因为您将制定使用和实施的指导方针和实践,每个人都将进一步增强他们对所选框架的了解,从而减轻您提出的问题之一 . 此外,您将了解在情况出现时哪些有效,哪些无效,最终将节省大量时间和精力 .

  • 12

    如果它是OLAP数据库(例如,用于报告/分析的静态,只读数据等),那么实现ORM框架是不合适的 . 相反,使用数据库的本机数据访问功能(如存储过程)将更为可取 . ORM更适合于事务性(OLTP)系统 .

  • 11

    我对Hibernate的体验是它的语义是微妙的,当出现问题时,有点难以理解引擎盖下的问题 . 我从朋友那里听说,通常一个人从Criteria开始,然后需要更多的灵活性并需要HQL,后来又注意到需要原始SQL(例如,Hibernate没有union AFAIK) .

    同样使用ORM,人们很容易过度使用现有的映射/模型,这导致有一个具有许多未初始化的属性的对象 . 因此在查询之后,内部事务Hibernate会进行额外的数据提取,从而导致潜在的减速 . 还遗憾的是,hibernate模型对象有时会泄漏到视图架构层中,然后我们会看到LazyInitializationExceptions .

    要使用ORM,人们应该真正理解它 . 不幸的是,人们很容易感觉到这很容易,而事实并非如此 .

  • 9

    运行时性能是我能想到的唯一真正的缺点,但我认为,当ORM为您开发/测试/等时,这不仅仅是公平的权衡 . 在大多数情况下,您应该能够找到数据瓶颈并更改对象结构以提高效率 .

    我之前没有使用过Hibernate,但我注意到一些“现成的”ORM解决方案缺乏灵活性 . 我确信这取决于你选择哪个以及你需要做什么 .

  • 3

    有很多常见的问题,像Hibernate这样的ORM工具是神派,还有一些是阻碍它的地方 . 我对你的项目知之甚少,不知道它是什么 .

    Hibernate的一个优点是你只能说3次:在类中提到了每个属性,.hbm.xml文件和数据库 . 使用SQL查询,您的属性位于类,数据库,select语句,insert语句,update语句,delete语句以及支持SQL查询的所有编组和解组代码中!这可能会很快变得混乱 . 另一方面,你知道它是如何工作的 . 你可以调试它 . 它就在你自己的持久层中,而不是埋藏在第三方工具的内部 .

    Hibernate可能是Spolsky的Leaky Abstractions法则的典型代表 . 稍微偏离常规路径,您需要了解该工具的深层内部工作原理 . 当你知道你可以在几分钟内修复SQL时,它会非常烦人,但你花了好几个小时试图哄骗你的dang工具来生成合理的SQL . 调试有时是一场噩梦,但很难说服那些没有去过那里的人 .

    编辑:你可能想看看iBatis.NET,如果他们不打算转向NHibernate,他们想要控制他们的SQL查询 .

    编辑2:这里是一个大红旗:“好的做法,在Stack Overflow上看起来很正常,例如单元测试或持续集成,到目前为止还不存在 . ”那么,这些“经验丰富”的开发人员,他们在开发方面经历了什么?他们的工作安全?听起来你可能是那些对这个领域不特别感兴趣的人,所以不要让他们扼杀你的兴趣 . 你需要保持 balancer . 投入了战斗 .

  • 3

    就个人而言,我(直到最近)反对使用ORM,并且习惯于编写封装所有SQL命令的数据访问层 . 对ORM的主要反对意见是我不相信ORM实现来编写正确的SQL . 而且,根据我以前看到的ORM(主要是PHP库)判断,我认为我是完全正确的 .

    现在,我的大部分Web开发都使用Django,我发现包含的ORM非常方便,而且由于数据模型首先用它们的术语表示,而且只在SQL的后期表达,它确实能够完全满足我的需求 . 我确信它不会太难以超出它并且需要补充手写的SQL;但对于CRUD访问来说绰绰有余 .

    我不知道NHibernate;但我想这对你需要的大部分内容来说也“足够好” . 但如果其他程序员不相信它;它将成为每个数据相关错误的主要嫌疑人,使验证更加繁琐 .

    您可以尝试在您的工作场所逐步介绍它,首先关注小的“明显”应用程序,如简单的数据访问 . 过了一会儿,它可能会用在原型上,它可能不会被替换......

  • 11

    The sweet spot of ORMs

    ORM对于自动化95%适用的查询非常有用 . 它们的特殊优势在于您拥有一个具有强大对象模型体系结构的应用程序和一个与该对象模型完美匹配的数据库 . 如果您正在进行新的构建并且在团队中具有强大的建模技能,那么使用ORM可能会获得良好的结果 .

    您可能会有一些手动更好的查询 . 在这种情况下,不要害怕编写一些存储过程来处理这个问题 . 即使您打算在多个DBMS平台上移植您的应用程序,依赖于数据库的代码也只占少数 . 请记住,您需要测试您的在您打算支持它的任何平台上应用程序,对某些存储过程进行一些额外的移植工作不会对您的TCO产生很大影响 . 对于第一个近似值,98%的便携式设备与100%的便携式设备一样好,远远优于复杂或性能不佳的解决方案,可以在ORM的极限范围内工作 .

    我已经看到前一种方法在一个非常大的(100年的员工年)J2EE项目中运行良好 .

    Where an ORM may not be the best fit

    在其他情况下,可能存在比ORM更适合应用的方法 . Fowler的企业应用程序架构模式有一个关于数据访问模式的部分,它可以很好地编写各种方法 . 我见过ORM可能不适用的情况的一些例子是:

    • 在具有大量遗留存储过程代码库的应用程序上,您可能希望使用功能导向(不要与功能语言混淆)数据访问层来包装现有的sprocs . 这将重用现有的(因此经过测试和调试的)数据访问层和数据库设计,这通常代表了相当大的开发和测试工作,并节省了将数据迁移到新数据库模型的麻烦 . 将Java层包装在传统的PL / SQL代码库中,或者使用Web界面重新定位富客户端VB,Powerbuilder或Delphi应用程序通常是一种非常好的方法 .

    • 变体是您继承不一定非常适合O-R映射的数据模型的地方 . 如果(例如)您正在编写一个从外部接口填充或提取数据的接口,那么最好使用direclty与数据库一起工作 .

    • 跨系统数据完整性很重要的财务应用程序或其他类型的系统,特别是如果您使用具有两阶段提交的复杂分布式事务 . 您可能需要比ORM能够支持的更好地管理您的交易 .

    • 您希望真正调整数据库访问的高性能应用程序 . 在这种情况下,可能优选在较低水平下工作 .

    • 你正在使用ADO.Net这样的现有数据访问机制的情况,这种机制“足够好”并且可以很好地与平台一起使用,这比ORM带来的好处更大 .

    • 有时数据只是数据 - 例如,您的应用程序正在使用“事务”而不是“对象”,并且这是域的合理视图 . 这方面的一个例子可能是财务包,您可以使用可配置的分析字段进行交易 . 虽然应用程序本身可以构建在O-O平台上,但它不依赖于单个业务领域模型,并且可能不仅仅了解GL代码,帐户,文档类型和六个分析字段 . 在这种情况下,应用程序不知道业务域模型本身,并且对象模型(在分类帐结构本身之外)与应用程序无关 .

  • 37

    每个ORM,甚至是“好的ORM”,都背负着一定数量的假设,这些假设与软件用于在应用层和数据存储之间来回传递数据的底层机制有关 .

    我发现对于中等复杂的应用程序来说,解决这些假设通常需要花费更多时间,而不仅仅是编写更直接的解决方案,例如:查询数据,并手动实例化新实体 .

    特别是,一旦您使用多列密钥或其他中等复杂的关系,您可能会遇到障碍,这些关系超出了您下载代码时ORM为您提供的便捷示例的范围 .

    我承认,对于某些类型的应用程序,特别是那些具有大量数据库表或动态生成的数据库表的应用程序,ORM的自动魔术过程可能很有用 .

    否则,与ORMs一起下地狱 . 我现在认为它们基本上是一种时尚 .

  • 32

    当您需要更新50000000条记录时 . 设置旗帜或其他什么 .

    尝试使用ORM without 调用存储过程或本机SQL命令来执行此操作 .

    更新1:尝试仅检索一个只包含少数字段的记录 . (当你有一个非常“宽”的表) . 或者是标量结果 . ORM也很尴尬 .

    UPDATE 2 :似乎EF 5.0 beta承诺批量更新,但这是非常热门的新闻(2012年1月)

  • 29

    首先 - 使用ORM不会使您的代码更容易测试,也不一定会在持续集成场景中提供任何优势 .

    根据我的经验,使用ORM可以提高开发速度,您需要解决的最大问题是:

    • 测试您的代码

    • 维护代码

    这些解决方案是:

    • 使您的代码可测试(使用SOLID原则)

    • 为尽可能多的代码编写自动化测试

    • 尽可能经常运行自动化测试

    未来对于你的问题,你列出的两个反对意见似乎更像是无知而不是其他任何事情 .

    无法手动编写SELECT查询(我认为,这就是为什么需要复制粘贴)似乎表明迫切需要一些SQL培训 .

    我不使用ORM有两个原因:

    • 公司严格禁止's policy (in which case I'去其他地方工作)

    • 该项目是数据密集型的,使用特定于供应商的解决方案(如BulkInsert)更有意义 .

    关于ORM的常见拒绝(特别是NHibernate)是:

    • 速度

    没有理由使用ORM比手动编码数据访问慢 . 事实上,由于内置的缓存和优化,它可以更快 . 一个好的ORM将生成一组可重复的查询,您可以为其优化模式 . 良好的ORM还允许使用各种提取策略有效地检索关联数据 .

    • 复杂性

    关于复杂性,使用ORM意味着更少的代码,这通常意味着更少的复杂性 . 许多使用手写(或代码生成)数据访问的人发现自己在"low-level"数据访问库上编写自己的框架(比如为ADO.Net编写帮助器方法) . 这些等同于更复杂,更糟糕的是,它们很少被记录良好或经过充分测试 .
    如果你正在专注于NHibernate,那么像Fluent NHibernate和Linq To NHibernate这样的工具也会减弱学习曲线 .

    让我了解整个ORM辩论的事情是,声称使用ORM的同一个人会太难/慢/无论使用Linq To Sql还是Typed Datasets都非常满意 . 虽然Linq To Sql是朝着正确方向迈出的一大步,但它仍然落后于一些开源ORM的落后时间 . 但是,Typed数据集和Linq To Sql的框架仍然非常复杂,并且使用它们太远(Table = Class)(基本CRUD)是非常困难的 .

    我的建议是,如果在一天结束时,您无法获得ORM,那么请确保您的数据访问与其余代码分开,并且您遵循Gang Of Four的编码建议一个界面 . 此外,获取一个Dependancy Injection框架来进行连接 .

    (咆哮怎么样?)

  • 5

    我认为不使用ORM有很多充分的理由 . 首先,我是一名.NET开发人员,我喜欢坚持.NET框架已经为我提供的内容 . 它做了我可能需要的一切 . 通过这样做,您可以采用更标准的方法,因此任何其他开发人员都可以在同一个项目中工作,从而能够获取所有项目并运行它 . Microsoft已经提供的数据访问功能非常充足,没有理由丢弃它们 .

    我已经做了10年的专业开发人员,领导了多个非常成功的百万美元项目,而且我从来没有编写过需要能够切换到任何数据库的应用程序 . 你为什么要一个客户这样做?仔细计划,选择合适的数据库以满足您的需求,并坚持下去 . 就个人而言,SQL Server已经能够做任何我需要做的事情 . 它很简单,效果很好 . 甚至还有一个免费版本,支持高达10GB的数据 . 哦,它与.NET一起工作很棒 .

    我最近不得不开始使用ORM作为数据层的几个项目 . 我觉得这很糟糕,还有一些额外的东西,我必须学会如何无缘无故地使用它 . 在极其罕见的情况下,客户确实需要更改数据库,我可以轻松地在整个数据层上重做工作,而不是花在与ORM提供商的愚弄上 .

    老实说,我认为ORM有一个真正的用途:如果您正在构建像SAP这样的应用程序,它确实需要能够在多个数据库上运行 . 否则作为解决方案提供者,我告诉我的客户端此应用程序旨在在此数据库上运行,就是这样 . 再过一次,经过10年和无数次的应用,这从来都不是问题 .

    否则我认为ORM适用于不太了解的开发人员,并且认为他们在应用中使用的第三方工具越多,他们的应用就越好 . 我会把这样的事情留给顽固的超级极客,同时我开发出更多优秀的软件,同时任何开发人员都可以拿起并立即提高工作效率 .

  • 1

    我在一个没有成功使用ORM的项目上工作过 . 这是一个项目

    • 从一开始就必须横向扩展

    • 必须快速发展

    • 有一个相对简单的域模型

    让NHibernate在水平分区结构中工作所需的时间比开发一个知道我们分区的超级简单数据映射器的时间要长得多方案...

    因此,我在ORM工作的90%的项目都是非常宝贵的帮助 . 但是在某些非常具体的情况下,我可以看到不使用ORM是最好的 .

  • 3

    ORM有两个方面令人担忧 . 首先,它们是由其他人编写的代码,有时是封闭源代码,有时是开源代码,但范围很大 . 其次,他们复制数据 .

    第一个问题导致两个问题 . 你依赖外人代码 . 我们都这样做,但不应轻率选择这样做 . 如果它不能满足你的需求呢?你什么时候能发现这个?你住在你的ORM为你画的盒子里面 .

    第二个问题是两阶段提交之一 . 关系数据库正被复制到对象模型 . 您更改了对象模型,它应该更新数据库 . 这是一个两阶段提交,而不是最简单的调试 .

相关问题