19

我有点害怕问这个问题,因为它可能会引发一场宗教战争,所以我想非常清楚我在寻找什么。我正在寻找您为什么会或已经以某种方式跳跃的原因,以及要添加到我列表中的项目。我正在寻找大票,大爆炸物品。此外,如果它们确实相关,则可能是特定于产品的项目。在这一点上,我正在尝试评估 ORM 与手动,而不是产品 A 与产品 B。

ORM的优势

- 快速编码和低维护(在某些/大多数情况下)
 - “免费”的附加功能(无需开发人员的努力)

手工编码的优势

- 更高效(在运行时,也许不是在开发时?)
 - 更少的复杂层
 - 大多数 ORMS 似乎都在为仅限于存储过程而苦苦挣扎

为了全面披露,我真的不喜欢在我认为合适的情况下对无法直接修改的数据库执行代码的“东西”的想法,但我可以看到 ORM 潜在的大量开发时间优势。

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

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

所以,稍微改变我的问题

有没有人在早期使用 ORM 构建应用程序,然后逐渐用手工编码的 DAL 代替?这种方法的缺陷是什么?

[进一步编辑——现在解决问题的核心]让一个网站能够对我的数据库执行任何 SQL 是可怕的。如果所有访问都是通过 sprocs 进行的,那么我的数据库将处于良好、安全、舒适的隔离状态。仅使用 sprocs 可以消除很多(如果不是全部)SQL 注入攻击向量。对此有何评论?

4

16 回答 16

16

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

于 2009-02-19T03:15:15.380 回答
7

我在几个大型项目中使用过 Subsonic。我不提倡使用一个 ORM 而不是另一个,但如果没有一个,我不会做另一个与数据库相关的项目。每当我更改数据库结构时重新生成整个数据库访问层的能力,在一个地方添加影响整个数据库层的功能的能力。

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

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

于 2009-02-19T03:48:33.057 回答
6

我已经编写和维护自己的 ORM 8 年了。它从 Java 开始,然后翻译成 C#。我无法想象没有它编写任何数据库支持的系统。它比 NHibernate 简单得多,并且没有它的所有功能,但它完成了工作,即使它广泛使用反射,它也相当快,因为​​它用 DAO 类定义上的反射替换了 XML 配置。

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

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

于 2009-02-19T03:16:20.170 回答
5

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

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

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

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

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

于 2009-02-19T03:06:55.060 回答
3

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

我的选择是 NHibernate。我现在真的是新手。但我也喜欢使用 Fluent NHibernate 或 Castle ACtiveRecord 的潜力。这似乎是心灵共享的地方。

但不确定在“一切都是存储过程”的世界中我会做什么。

于 2009-02-19T03:03:44.287 回答
3

你试过红豆吗?在开发阶段,它流畅且易于使用,而在生产模式(冻结)中,它的速度很快。 http://redbeanphp.com

于 2009-07-30T06:26:46.477 回答
3

我认为 ORM 只是在一开始就“快速编码”,特别是如果您没有现有的已安装模式。一旦您需要开始从系统中榨取更多性能,您将需要一个可以“快速处理”的 ORM。

我发现它们是一罐蠕虫。

于 2011-07-04T09:24:16.403 回答
1

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

于 2009-02-19T03:49:34.333 回答
1

我继承了一个使用 NHib 和 MyGeneration 创建的网络应用程序,遗憾的是没有获得 svn 存储库,并且不再具有初始模板 (arrggg)。

为创建/更新/删除后端的东西保持休眠状态,但前端(只读)有点愚蠢地实现,像一条两条腿的狗一样运行,现在正在用普通的旧 ADO.NET 重写,并且上升快 10 倍。

我并不是说这是由于 NHibernate,而是由于开发人员不知道他们通过网络发送了多少垃圾,并假设盲目使用工具意味着他们不必考虑它。

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

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

我个人偏爱 SubSonic,我发现它在中型项目中表现相当不错,如果你发现瓶颈,你可以手动解决它。

工具很棒,任何能给我更多周末的东西都很棒,但没有什么可以替代你耳朵之间的工具。

于 2009-02-19T04:08:18.093 回答
1

评论您的存储过程问题。无论功能如何编写,DAL、ORM、存储过程,都会涉及到 SQL。如果您使用存储过程,您可以在里面编写 SQL,并且构建有用的抽象相对容易。如果使用 DAL,则编写 SQL,但在实践中,它更有可能是未抽象的 SQL,并增加了注入的风险。如果您使用 ORM,该工具会编写 SQL(但您最终要对它负责 - 包括可注入性)。恕我直言,移动部件(尤其是您知道和理解的部件)越少越好。

于 2009-04-27T02:59:14.910 回答
1

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

  • 具有查询覆盖的透明延迟加载
  • 实体身份(始终获得相同实体的相同引用)
  • 插入/更新批处理
  • 选择批处理(NHibernate 中的期货)
  • 身份生成
  • 将查询 API 转换为 sql(由于查询 API 的模块化特性,标准是完美的)

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

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

我无法想象如何手工编写比 NHibernate 生成的性能更好的 sql。反对的一些论据:

  • 当只需要很少的属性时加载整个对象 --> 总是投影到 DTO 或在 C# 3.0 中到匿名类型 (SetProjection() / Select())
  • 许多选择而不是连接 -> 在需要的地方使用急切加载(SetFetchMode()/ Fetch())
  • 调整后的 sql 总是比生成的性能更高 --> 架构优化 >> 微优化,使用 ORM 重构架构要容易得多,因为代码更少,重复逻辑更少(尝试将一对多更改为多对-许多手写的dal)
于 2012-01-13T16:29:12.653 回答
0

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

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

于 2009-02-19T03:07:35.150 回答
0

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

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

我选择 Castle 的原因是它非常易于使用。使用 Visual Studio 的 activewriter 插件,我能够使用设计器(有点像 linq to SQL 设计器)生成我的类和数据库,并且它似乎很适合我关于 ORM 应该如何决定你的应用程序架构的心智模型.

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

因此,我使用 ORM,为自己节省了很多前期工作,但是当我试图解决框架生成过多 SQL 的问题时,我遇到了麻烦。(我仍在慢慢工作)。

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

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

于 2009-02-19T03:45:37.150 回答
0

好问题和好答案。我也刚刚涉足这些问题。我更喜欢像 SubSonic 这样的 ORM 来手动编码 DAL。

于 2009-04-27T02:43:37.787 回答
0

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

几年前,我重新编写了一个基于数据库的 PHP Intranet 应用程序。与许多“刚刚成长”的 PHP 应用程序一样,它没有使用任何类型的 ORM,并且有很多重复的代码,其中大部分以不同的方式组装相似的查询。

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

回想起来,这对我来说是一个非常有用的练习。这意味着我现在知道 ORM 层是如何工作的以及它们必须如何工作。它也与大量数据库扩展的趋势背道而驰,因为它把问题带到了应用程序中,即有关数据的知识所在的地方。

于 2009-04-27T03:06:42.990 回答
0

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

如果请求是插入数据:

如果请求是选择数据:

  • 编写一个存储过程以使用多个 SELECT 语句吐出数据。
  • 将该数据加载到 DataSet 中(确保在需要的地方建立“嵌套”关系)。
  • 在 DataSet 上使用 GetXml() 以转换为 SOAP 中使用的 XML。

我已经在几个生产环境中成功地使用了这个过程。如果您知道您只会使用 SQL Server,它会快速而简单。

于 2009-07-10T21:21:13.067 回答