我很惭愧,但我不得不说。我没有使用过ORM。我真的在考虑 NHibernate,因为它似乎是最成熟的 .Net 产品(如果我错了,请纠正我)。现在,问题是我们有一个以 SqlServer 作为主要集成点的大型电子商务/预订系统,在存储过程中包含相当多的业务逻辑。现在 - 显然 - 这种架构是我们想要摆脱的东西,我们已经这样做了一段时间,一点一点。所以,我真正的问题是,开始使用 NHibernate 来开发新功能而不是返回并映射所有遗留的东西有多可行?这种渐进式的引入和ORM是否支持,如果支持,你会推荐吗?
8 回答
如果您使用的是遗留数据库,您会发现 ORM 工具相当难以使用、配置、维护和优化。当我们使用 NHibernate 将我们的域模型映射到现有数据库时,我们遇到了许多问题。其中一些是:
模型对象很难映射到现有的表(我们有超过 100 个表),NHibernate 的一些要求非常突出,例如每个表都必须有一个 ID 字段才能映射到域对象。此外,映射多对多关系非常难以掌握和使用。
维护映射到遗留数据库所需的大量映射 XML 成为开发人员的全职工作,并且非常具有挑战性,特别是在 10 多名开发人员的团队中。
随着复杂性的增加,我们的查询性能下降,因为数据模型和对象模型并不总是与业务匹配并且需要不断调整。必须编写大量数据聚合代码。例如,如果我们需要显示一个连接多个表的网格,我们过去必须加载多个域对象,将它们放在一起并显示在一个网格中。该代码很难维护和调试。
此外,有时我们必须运行匿名查询,即我们只需要一些对象的一些属性而不是整个对象。这真的很难编写、维护甚至实现,并且违背了 ORM 范式,但我们别无选择,只能这样做。
我们遇到的另一个问题是数据库不断变化,因为 DBA 会重构表,这总是会破坏我们的域对象。保持模型和表格同步并确保应用程序仍然有效是一项练习。
长话短说……我们了解到,如果有一种方法可以将业务所需的 SQL 直接映射到我们的 UI 模型或域对象而无需担心配置,那将是一个更好的解决方案。
在经历了这些经验之后,我们开发了 Orasis Mapping Studio。它是一种专门设计用于处理遗留数据库以及现有 .NET 模型/域对象的映射工具。它采用您的 SQL 查询,并允许您通过以图形方式显示查询和对象的元数据并使用拖放创建对象属性和查询列之间的映射,将它们映射到现有的 .NET 对象。该工具会自动生成执行映射以读取对象所需的所有 ADO.NET 代码。然后,您可以在 DAL 层中使用生成的代码或使用生成的程序集来检索和保存您的数据。
您可以在这里尝试:Orasis Mapping Studio。它是我们认为开发人员真正需要的工具,特别适用于处理遗留数据库以及性能是关键要求的地方。它是由开发人员为开发人员编写的,因此它处理了一些复杂的细节,如对象继承、嵌套对象、数据类型转换等。祝你好运!
这将取决于您当前数据库的“NHibernate 友好”程度。NHibernate 喜欢单列主键(如果它们都被命名为“id”就更好了)。据我所知,大多数 ORM 对存储过程都不是很友好。您是否考虑过如何定义传输对象以从数据库来回获取数据?
顺便说一句,没有什么可耻的。ORM 是个好东西,但你试图找到最好的方法是对的。
我没有亲自这样做过,但是您可以将命名查询中的存储过程复制粘贴到映射文件中,然后再将它们一一删除。
如果您对 ORM 没有任何经验,可能很难在大型遗留项目中开始学习它,因为您必须发现 ORM 的所有非标准特性,这些特性不会在新建项目中使用,或者使用一年只有一次。NHibernate 有很多选项来支持遗留数据库。
当你准备好跨越学习曲线并勇敢地开始使用新技术时,你可以从 NHibernate 开始,但是如果你想逐步学习新技术,我会等到 NHibernate 开始一个新的未开发项目。
任何体面的 ORM 工具都应该支持渐进式集成。这里的技巧是在 DAO 级别(数据访问对象层)进行明确的分离。如果您可以通过定义明确的 API 隐藏您的数据访问怪癖,那么您是否使用 ORM 并不重要。
话虽如此,ORM 引入的复杂性与表模型的复杂性直接相关。对于同一个表,您可以有许多不同的映射,只需确保您事先进行了一些试验,以了解 ORM 解决方案的怪癖,例如对象缓存、后写查询、代理访问等。ORM 解决方案的真正好处是使用对象而不是虚拟 POJO 类。这使得对业务进行更改比使用存储过程或平面对象容易得多。
作为旁注,我参与了一个项目,我们将 sprocs 中的整个应用程序迁移到 java。虽然我们没有使用 sproc,但真正的痛苦是 sprocs 架构没有很好地定义,许多 sprocs 调用其他 sprocs 使得一次只迁移一些 sprocs 变得非常困难。
NHibernate 中没有任何东西会限制你这样做。在某些时候,您可能希望将旧代码转换为也使用 NHibernate,因为在您可以导航所有对象之间的关系之前,您不会看到 ORM 的全部好处。
最大的挑战可能是让您的旧表结构适合 NHibernate 的每类单表方法。有一些方法可以解决这个问题,但这可能很棘手。不过,我认为这是值得的。
您曾提到您正在远离您当前的架构,但是您是否需要坚持您的遗留数据库设计(例如,DBA 严格负责设计和维护它)或者您当前的数据库设计是否正在重构(考虑到 O /R 映射器)以及?
如果很难摆脱当前的遗留设计,您可能会考虑使用普通的旧 T-SQL 查询,而不是不太灵活的 Hibernate 样式,使用iBATIS SqlMap 来将实体 O/R 映射到遗留数据库。映射数据的 XML/属性。
根据您希望如何进行设计,您可以通过使用您自己的抽象DAO工厂或iBATIS DataAccess API(本质上就是这样做的,并且仍然与N休眠。)
我同意艾哈迈德所说的话,我过去也遇到过类似的问题。我遇到的大部分麻烦不是来自技术本身,而是来自开发人员的采用,改用 NHibernate 意味着工作习惯的改变,至少可以说,这并不总是那么容易。
如果您是 ORM 新手,那么使用它开始一个全新的项目可能比尝试转换旧项目更好。
我将遗留项目转换为 ORM 的建议是尝试使用某种生成工具,如 LLBGen 或 .netTiers 甚至 Linq2SQL。通过这种方式,您可以更轻松地使用 ORM,而无需 NHibernate 可能强加的创伤性重写。
为什么存储的过程“明显”不好?存储过程中的业务逻辑是否会引起痛苦?
Microsoft 似乎有许多可用的持久性技术(例如,LINQ)。我不知道如何评估它们与 NHibernate,但我不会推荐 ORM,除非你有非常好的对象可以映射到。