【问题标题】:ORM modeling: Database first vs classes firstORM 建模:数据库优先 vs 类优先
【发布时间】:2014-07-20 01:27:44
【问题描述】:

我正在尝试使用 Sparx Enterprise Architect 设计一个数据模型,该模型最终将存储在 MySQL 数据库中。

我的第一个方法是Data Model diagram,它可以用于generate DDL(或相反的reverse engineering)。

这很有效,但一位同事指出了一个问题:我们打算使用 ORM(几乎可以肯定是 Hibernate)将表映射到 Java 类。他的评论是“数据库优先”的方法会排除使用良好的 OO 技术,例如继承。

这似乎是一个好点,但我想知道是否有任何限制。如果我从头开始使用Class Diagram 而不是数据模型图,是否有办法在此模型中包含所有必要的 Hibernate 注释、配置等?而且,如果我以后需要对特定于数据库的功能(例如约束、触发器等)进行建模,考虑到类图并非真正针对此类事物,所有这些都可以在模型中实现吗?

【问题讨论】:

  • 我总是喜欢从数据模型图开始,并以此为基础创建我的类图,然后以尽可能简化我的工作的方式映射我的类。
  • 谢谢,你的意思是你手动生产吗?理想情况下,只需要维护一个图表并将其用作生成类和数据库模式的单一来源(在模型外部使用最少的“接线”)。
  • 在这种情况下,我会维护数据模型图,但我认为答案取决于人本身以及您喜欢的工作方式。
  • 嗯,我更熟悉数据库优先的方法,但从未使用过类优先的方法。如果这样做,问题实际上是关于识别模型中无法捕获的任何内容(即类图)。

标签: java mysql hibernate orm enterprise-architect


【解决方案1】:

我更喜欢先对数据库建模。数据库是业务中最有价值的部分,应用程序逻辑只是操作业务数据的接口。

由于数据库往往比应用程序技术更长寿,因此最好提前设计它,因为设计通常由数据关系和数据查询模型驱动。

大多数 ORM 旨在将域对象建模为现有架构,处理任何可能的数据库架构映射问题是 ORM 工具的任务。

对于快速原型制作,我可能会考虑让我的架构从域对象生成,但在设计大型企业系统架构时,这种方法不是最佳的。

Hibernate 仅提供有限数量的 DDL 功能,我不喜欢放弃额外的 DB 特定功能,例如 PosgreSQL domainsinstead-of triggersmaterialized viewsMySQL triggers

Flyway 之类的工具最好用于自动执行架构迁移过程。

【讨论】:

  • 一些很好的例子,但是这些似乎都与 MySQL 无关。我想知道的一些事情是 MySQL 触发器和控制索引、外键和引用完整性 (ON DELETE RESTRICT/CASCADE/SET NULL/NO ACTION) 等的所有 Hibernate 注释。
【解决方案2】:

无论您使用何种技术,您都应该始终“真理至上”。 XML 接口的真相在哪里?在其 XSD 规范中,不是任何任意语言的一些实现类。同样,与 RDBMS 交互时,真相在哪里?它在数据库中,以 DDL 的形式编写。数据库应该“拥有”它的模式,而不是从一些派生的客户端表示中生成它。 I've written about this topic here.

这是使用对数据库重要的语言控制数据库架构的唯一合理方法。这也是合理的唯一方法:

  • 一旦上线就发展架构,不能只是简单地删除并重新创建它
  • 保持对数据库性能的控制,尤其是当您编写 SQL 查询而不是使用 ORM 来导航您的实体时。

我们打算使用 ORM(几乎可以肯定是 Hibernate)将表映射到 Java 类。他的评论是“数据库优先”的方法将排除使用良好的 OO 技术,例如继承。

首先你应该问自己为什么需要继承。由于您使用关系模型存储数据,因此您应该使用关系模型的建模功能,并且所有客户端表示(例如您的 ORM)都应该从中派生。在极少数情况下,继承在这个领域甚至是一种可行的建模技术,而且大多数情况下它仍然不能很好地工作,因为经过 20 多年的 OO,人们得出结论,在 OO 早期,继承被过度使用——尤其是继承的数据结构。构图应该受到青睐,并且无论如何都更具关联性。

您的关系模型有可能比您的 OO 客户端表示更长寿,您应该确保关系模型是健全且规范化的,等等。

这似乎是一个好点,但我想知道是否有任何限制。如果我从头开始使用类图而不是数据模型图,是否有办法在此模型中包含所有必要的 Hibernate 注释、配置等?而且,如果我以后需要对特定于数据库的功能(例如约束、触发器等)进行建模,考虑到类图并非真正针对此类事物,所有这些都可以在模型中实现吗?

我认为您不需要通过派生类图来导航您的数据库模型。考虑您的 ERD(您可以从 DDL 生成)。 ORM 的表示将简单地反映这一点。

【讨论】:

    【解决方案3】:

    领域模型优先,永远如此。 然后DB和Entity同时进行。

    【讨论】:

      【解决方案4】:

      让我问一个问题来回答:如果你要建房子,是先建房子再做蓝图,还是先做计划? :)

      软件开发就是逐渐降低抽象。我们从一个非常抽象的项目想法开始,然后提出一些需求(这显然不那么抽象),然后架构、设计和精细到编码级别(最低抽象)

      数据模型是可能的最低抽象级别的模型(直接映射到 DDL),所以这是你要做的最后一件事。

      域类模型是对数据库的更高抽象。它甚至是对 Hibernate 层的抽象,因为它也位于抽象的实现层面。

      因此,我首先肯定会使用类和 OO 的全部功能对域进行建模。尝试使实现独立的类模型。不要假设 JAVA、Hibernate、DB 等任何东西,而是专注于您的域逻辑。制作一种“乌托邦”领域模型,逻辑上结构完美的领域类。

      然后使用相应的转换从这个模型中派生 Hibernate 层和 DB 本身。

      【讨论】:

        【解决方案5】:

        这是领域驱动设计的一票,类/代码优先。

        首先创建休眠实体类,这就是您将要编码的内容 - 正确处理这些内容,为什么要关心持久化的内容 - 因为您不打算编写 sql (?)。我的过程是创建类,如果你需要的话,从它们中吐出 uml(虽然很少有这种资源的奢侈),然后让 hibernate 构建数据库。

        我尽量避免使用供应商特定的数据库功能 - 根据定义,它会有点奇怪。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-12-06
          • 2023-03-11
          • 2011-07-23
          • 1970-01-01
          • 2018-04-16
          • 2011-04-17
          • 1970-01-01
          相关资源
          最近更新 更多