ORM与手动编码数据访问层

时间:2009-02-19 02:52:51

标签: orm data-access

我有点害怕问这个问题,因为它可能会开始一场宗教战争,所以我想要清楚地知道我在寻找什么。我正在寻找一个理由,为什么你会或者已经或者已经跳过了某种方式以及将项目添加到我的列表中。我正在寻找大票,大爆炸物品。此外,产品特定的项目,如果它们真的相关,也许。此时我正在尝试评估ORM与手动而非产品A与产品B的比较。

ORM优势

 - Quick to code and low maintenance (in some/most scenarios) 
 - Additional features for "free" (no developer effort)

手工编码优势

 - More Efficient (at runtime, maybe not at dev time?)
 - Less layers of complexity
 - Most ORMS seem to struggle with being retricted to sprocs only

为了充分披露,我真的不喜欢“某事”对我的数据库执行代码的想法我无法直接修改,如果我认为合适但我能看到ORM潜在的大规模开发时间优势。

它可能也值得注意我在.Net世界

[编辑] (Using an ORM or plain SQL?的问题似乎回答了许多问题并强调了关于绩效的观点)

所以,稍微改变我的问题

是否在早期阶段使用ORM构建了应用程序,然后逐渐用手动编码的DAL替换?这种方法的缺陷是什么?

[进一步编辑 - 现在解决问题的核心] 让网站能够对我的数据库执行任何SQL是可怕的。如果通过sprocs进行所有访问,我的数据库将保持良好,安全,舒适的隔离。使用专门的sprocs删除了很多(如果不是全部)SQL注入攻击向量。对此有何评论?

16 个答案:

答案 0 :(得分:15)

我们最初使用JPA编写了一个应用程序,自投入生产之日起我们就后悔了。 ORM进行的数据库调用量是天文数字,因此我们现在开始使用Spring的JDBC帮助程序类,使用优秀的JDBC来重新编写应用程序。从ORM开始的缺陷是我们花了大量时间学习JPA,并且在一天结束时我们必须用JDBC替换它,这样我们的应用程序可以更加可扩展,而无需向Oracle RAC添加其他3个节点。因此,如果你平衡它,JDBC的控制和精度值得你必须编写额外的代码行。此外,大多数人不理解SQL不是可以生成和期望执行的东西。这是必须编写和调整以获得最大性能的东西。

答案 1 :(得分:7)

我已经将Subsonic用于了几个大型项目。我不是主张使用一个ORM而不是另一个,但我不会做一个与数据库相关的项目。每当我更改数据库结构时,都能够重新生成整个数据库访问层,能够在一个地方添加影响整个数据库层的功能。

问题是您必须了解它与数据库的交互方式,否则您将面临编写(严重)代码不足的风险。您的ORM工具可能会为您提供一个很好的面向对象的数据视图,但您可能会发现您正在将整个表格流式传输到客户端以进行简单的处理。数据库擅长关联和过滤数据,因此请确保它仍然具有该作业。具有讽刺意味的是,Subsonic缺少连接(在我使用的版本中),这有助于此,因为它迫使我创建数据库视图以在需要时组合数据。

我的一个朋友和一个开发了内部ORM工具的人一起工作。它有一个很好的功能,可以通过遍历外键来本地缓存您可能想要从数据库中获取的所有内容。缺点是从DB中的一行读取一列导致超过11,000个选择语句。

答案 2 :(得分:6)

我已经编写并维护自己的ORM已有8年了。它始于Java,然后转换为C#。没有它,我无法想象编写任何数据库支持的系统。它比NHibernate更简单,并且没有它的所有功能,但它完成了工作,即使它广泛使用反射也很快,因为它用DAO类定义的反射取代了XML配置。

我对它很满意,不会使用任何其他方法。

编辑:关于SQL注入攻击:我使用这个ORM开发的最新系统经过了广泛的审核,绝对不允许注入。原因很简单:它动态生成SQL,始终使用参数,没有字符串连接。

答案 3 :(得分:5)

几个星期前,我开始开发一个新项目。我完全控制了我可以使用的工具。我从db40开始,因为我想完全消除这个问题;我只想直接保留我的对象,忘记ADO.NET或OR / M.但db40有问题,所以我要放弃它。

我的下一个选择是ADO.NET,因为我认为它会快速而简单。但是我不得不写太多的代码,使用太多的“字符串sql”,这只是一件苦差事。我的意思是,这是一个皇家PITA,在编写了两个存储库之后,我想切割我的手腕。

我的第三个选择是NHibernate。在我需要使用断开连接的对象的情况下,我之前遇到过NHibernate的问题(这次也是这种情况,因此为什么我花了三次尝试才得到它)。但那是NHibernate 1.2。这次我获得了2.0二进制文件,并且没有更新断开连接的对象的问题。我还必须编写更少的代码行,当我需要重构事物时它非常简单,这可能是最重要的,因为我的设计变化很快。

我现在在NHibernate上卖了。它似乎也高度优化。老实说,我找不到它的负面影响。并且没有存储过程。

我知道这是我选择的OR / M,我再也不会直接写ADO.NET了。

答案 4 :(得分:3)

我几年来一直在努力解决这个问题。看了很多东西。并且在过去的3个月里意识到“为什么我一直都在浪费这个”。我认为ORM是一个已解决的问题。我宁愿相信一些完全专注于ORM的团队来编写ORM层而不是我。在精神上,我只是准备迎接新的挑战。

我的选择是NHibernate。我现在真是个新手。但我喜欢使用Fluent NHibernate或Castle ACtiveRecord的潜力。这似乎是思想分享的地方。

但不确定我会在“一切都是一个蠢货”世界中做些什么。

答案 5 :(得分:3)

你尝试过redbean吗?在开发阶段,它的流动性和易于使用,而在生产模式(冷冻)它的速度快。 http://redbeanphp.com

答案 6 :(得分:3)

我认为ORM只是在一开始就“快速编写代码”,特别是如果你没有现有的已安装架构。 一旦您需要开始从系统中挤出更多性能,您将需要“快速处理”ORM。

我发现它们是一种蠕虫病毒。

答案 7 :(得分:1)

存储过程不会消除sql注入的风险。可能在代码中连接查询的人在存储过程中也可能这样做。并且任何好的ORM都不会进行字符串连接,所以没有问题。

答案 8 :(得分:1)

我继承了一个用NHib和MyGeneration创建的网络应用程序,遗憾的是没有获得svn repo,也没有初始模板(arrggg)。

为创建/更新/删除后端内容保留了nhibernate,但是前端(只读)有点无法实现,并且像一条2条腿的狗一样运行,现在正在用普通的旧ADO.NET重写,并且速度提高了10倍。

我不是说这是由NHibernate引起的,这是因为开发人员不知道他们在线上发送了多少废话,并且假设盲目使用工具意味着他们不必考虑它。 / p>

出于只读查询的目的,您通常可以更有效地手动编写它们。

对于必须写入数据库的东西,通常更容易,而且速度慢得多,让一个像样的ORM去做。

我个人喜欢SubSonic,我发现它对中型项目表现相当不错,如果你发现瓶颈,你可以手工解决。

工具很棒,任何给我更多周末的东西都是双倍的,但是你的耳朵之间没有任何替代工具。

答案 9 :(得分:1)

评论您的存储过程问题。无论函数如何编写,DAL,ORM,存储过程,都会涉及到SQL。如果使用存储过程,则在内部编写SQL,并且构建有用的抽象相对容易。如果您使用DAL,则编写SQL,但实际上,它更可能是未经提取的SQL,并增加了注入的曝光率。如果您使用ORM,该工具会编写SQL(您仍然负责 - 包括注入性)。恕我直言,移动部件最少(特别是你熟悉和理解的部分)越​​好。

答案 10 :(得分:1)

我不得不重写使用对象数据库的生产应用程序的DAL。我们希望同时支持对象DB和SQL数据库。我真的不想实现一些功能,其中已经存在的功能是

  • 使用querywise覆盖进行透明延迟加载
  • 实体标识(对于相等的实体,始终获得相同的参考)
  • 插入/更新批处理
  • 选择批处理(NHibernate中的Futures)
  • ID代
  • 将查询API翻译为sql(由于查询API的模块化特性,条件是完美的)

这就是为什么我选择NHibernate作为我的ORM,我很高兴。我免费获得了一些不错的功能。

  • 自动化类(总共3页代码以生成整个映射)
  • LINQ支持(曾经尝试过自己实现LINQ-provider?)
  • 免费广泛记录
  • 使用inmemory sqlite进行更简单的单元测试
  • 支持不同的数据库提供程序
  • 模式生成非常简单(不必为不同的数据库提供程序维护任何生成脚本)
  • 乐观并发
  • N / Hibernate的文档是关系技术的一个很好的学习资源

我无法想象如何手动编写性能更好的sql而不是NHibernate生成的。一些反对的论点:

  • 只需要很少的属性时加载整个对象 - >总是投影到DTO或C#3.0中的匿名类型(SetProjection()/ Select())
  • 许多人选择而不是加入 - >在需要的地方使用预先加载(SetFetchMode()/ Fetch())
  • 调整后的sql总是比生成的更高效 - >架构优化>>微优化,使用ORM,重构体系结构要容易得多,因为代码更少,重复逻辑更少(尝试在手写dal中将一对多更改为多对多)

答案 11 :(得分:0)

您不需要像nHibernate一样使用良好的ORM放弃您的SPROC或手工制作的SQL。

事实上,我已经取代了我的ORM数据访问方法,它并不难,它是两全其美的。

答案 12 :(得分:0)

我已经将Castle Project的Active Record实现与NHibernate一起用于个人项目。该项目从未部署过,部分原因是我无法使用我所做的ORM选择。

我决定使用ORM的原因是因为我希望能够在不更改代码的情况下从SQL Server切换到MYSQL。在实际项目中,我已经决定使用SQL服务器,当您知道数据库不会更改时,以传统的3层方式编写数据层更容易。 但对于个人项目,我使用共享主机,MySQL是一种更便宜的解决方案。

我选择Castle的原因是因为它非常容易使用。使用visual studio的activewriter插件,我能够使用设计器(类似于linq to SQL设计器)生成我的类和数据库,它似乎与我的心理模型非常吻合,ORM应如何规定您的应用程序架构

我对ORM的问题是我无法找到有关如何正确优化它的信息。它正在对数据库进行非常大的调用。 (为了获取用户而生成的SQL查询在我记录时是1mb的文本。)

所以,我使用ORM,我预先为自己节省了大量工作,但是当我尝试用框架生成太多SQL来解决问题时,我遇到了问题。 (我还在慢慢地工作)。

即使我没有找到完美的解决方案,我仍然会尝试ORM用于其他个人项目,因为它只是我,我想把我的项目时间花在有趣的代码上,而不是数据层。

然而,在工作中,在我成为专家之前,我可能不会太快地建议我们使用ORM(也许在我接受了几个有用的个人项目之后)。

答案 13 :(得分:0)

很好的问题和很好的答案。 我刚刚参与了这些问题。 我更喜欢像SubSonic这样的ORM来手动编码DAL。

答案 14 :(得分:0)

好的,这是一个PHP应用程序,而不是.net,但我认为相同的品质很重要。

几年前我重写了一个基于数据库的PHP内联网应用程序。正如许多已经“成长”的PHP应用程序的典型情况一样,它没有使用任何类型的ORM并且有很多重复的代码,其中大部分以不同的方式组装类似的查询。

我粗略地看了一些ORM框架,但它们都有一个大问题:他们需要自定义它们才能在我们的结构中工作。缺少的重要组件是数据库可伸缩性。所以我写了自己的处理程序。然后继续前进并构建我们自己的基于对象的数据层是一件简单的事情。我们必须实现我们想要的功能,这样做了我们需要的功能。

回想起来,这对我来说是一项非常有用的练习。这意味着我现在知道ORM层如何工作以及它们如何工作。它也挫败了大量数据库扩展的趋势,因为它将问题提升到应用程序中,在那里有关于数据的知识。

答案 15 :(得分:0)

我在.Net中使用DataSet非常成功。我们有一个SOAP端点,它首先使用.XSD验证输入。然后,您可以使用规则引擎进行一些验证。然后...

如果请求是插入数据:

  • 在DataSet上使用GetXml()转换为XML。
  • 将XML发送到在SQL Server中使用OPENXML的sproc。

如果请求是选择数据:

  • 编写一个sproc以使用多个SELECT语句吐出数据。
  • 将数据加载到DataSet中(确保在需要时构建“嵌套”关系)。
  • 在DataSet上使用GetXml()来转换为SOAP中使用的XML。

我在多个生产环境中使用此过程取得了很大成功。如果你知道你只使用SQL Server,它会快速而简单。