ORM - 是不是需要 DDL 脚本?

Posted

技术标签:

【中文标题】ORM - 是不是需要 DDL 脚本?【英文标题】:ORM - Are DDL scripts required?ORM - 是否需要 DDL 脚本? 【发布时间】:2018-06-14 23:11:25 【问题描述】:

Answer 说,不要相信 hibernate.hbm2ddl.auto 的生产设置。

我对使用ORM的理解:

1) 避免在数据库层(比如 RDBMS)设计和规范化数据库模式。在 mongoDB 世界中,使用的是 ODM。

2) 避免在代码中嵌入 SQL 查询语言(比如 java)。

3) 只考虑存储和检索对象(在 OOP 意义上)


运行 DDL 脚本打破了使用 ORM 工具的目的,看起来类似于 JDBC 方法,只是它为特定于供应商的数据库提供 SQL 方言。

对于生产,是否可以强制运行 DDL 脚本以确保安全?

【问题讨论】:

"手动运行 DDL 脚本会破坏使用 ORM 工具的目的。" - 谁说的? (并不是说你必须手动运行它们,你可以使用 Flyway 之类的工具来管理你的 DDL 脚本的执行) @ErwinBolwidt 啊,手动还是其他方式都无所谓。 ORM主要是为了避免这个阶段 不,不是。您似乎误解了 ORM 的用途。 Java 中的 ORM 工具大多(总是?)运行在 JDBC 之上。它们是一种抽象,意味着您可以与对象交互而不是编写 SQL 查询,自动方言翻译是它们提供的一个非常小的功能。 JPA 特别是(Hibernate 实现的)还可以帮助您进行会话和事务管理。 ORM 绝对不是关于“避免在 RDBMS 世界中设计和规范化模式”。不过,它与 23 有更多关系。 ORM 使您能够编写面向对象的代码以与数据库交互。您仍然应该首先设计您的数据库,然后在数据库的结构之后映射您的类 - 而不是相反。使用 ORM 不会以任何方式防止您遇到结构不良的表的问题。 【参考方案1】:

是的,它们是必需的。如果你想高效地工作,那就是。

手动运行 DDL 脚本破坏了使用 ORM 工具的目的

不,它没有。 ORM 代表 Object Relational Mapping,意思是将 RDBMS 的关系数据映射到 Objects。这并不意味着数据库模式必须由 ORM 更改,即使存在这种可能性(并且在非常简单的情况下也有效)。

此外,您不会手动运行任何东西。有像Flyway 和Liquibase 这样的数据库迁移/重构产品试图解决数据库模式随时间变化的问题。它们也是独立的产品,因此您无需关心您使用的是 Hibernate 还是其他一些数据访问方法。他们还尝试提供一定程度的事务性,这意味着您可以在某些情况下恢复对架构的更改。

在任何不平凡的项目中,人们都会尝试确保他们可以改进数据库,而不会被永久锁定在旧架构中,并确保数据保持安全。为此目的而设计的适当工具会使它变得容易得多,而 ORM 的半生不熟的机制则不然。

【讨论】:

那么,我可以说ORM主要是使用Hibernate而不是DDL来运行DML操作(为了安全)吗? —— 这与安全无关。这是为了方便。在玩具项目中,您还可以自动更新架构,但除了最简单的情况外,这不是一个可行的选择。 在生产中,使用Hibernate进行DML操作是否更方便?并单独运行 DDL 脚本【参考方案2】:

手动运行 DDL 脚本会破坏使用 ORM 工具的目的。

不,它没有。

Object-Relational Mapping 工具可帮助将表中的数据转换为可在面向对象编程语言中使用的对象 - 它与数据库管理无关。 p>

Hibernate 可以根据您的类现在的样子生成 DDL,但它没有历史感。

如果您所做的只是添加新的列或表,您可能会没事,但是当您重命名列时,您就不走运了,因为 Hibernate 会看到旧列并且找不到到它的映射因此它将删除它,然后使用新名称创建一个新列。如果您对该列有非空要求,那么您就搞砸了,因为您无法告诉 Hibernate 的默认值是什么(好吧,有一个 hack 但请不要这样做。)

您在如何更改列类型方面也非常有限 - 如果列的内容不能被数据库自动翻译,那么您就不走运了。

作为一个例子,我们将我们的数据库从以二进制存储 UUID 转换为将其存储为 VARCHAR 不久前,我们不得不手动将它们从二进制转换为十六进制表示法,因为 mysql 无法自动执行此操作 - 你会正确如果您尝试使用 Hibernate 的自动 DDL 来做到这一点,那就搞砸了。

也没有办法告诉 Hibernate 在哪里创建索引 - 您将在每个主键列上获得一个索引,但如果您需要额外的索引,则必须手动添加这些索引。

Hibernate 的 DDL 自动生成有助于验证您的类是否正确映射到您的表,但绝不应该使用它来更改您的生产数据库。

所以回答你的问题:

对于生产,是否必须手动运行 DDL 脚本以确保安全?

是的!我建议您使用像 Liquibase 或 Flyway 这样的管理工具来帮助它。

【讨论】:

你能分享一些关于什么是休眠和不是休眠的资源吗? 我真的找不到任何资源来讨论 Hibernate 不是,但是如果您阅读有关 ORM、JPA 和 Hibernate 的介绍,您就会明白它们旨在解决哪些问题(即关系数据访问和 RDBMS 中的操作)。

以上是关于ORM - 是不是需要 DDL 脚本?的主要内容,如果未能解决你的问题,请参考以下文章

DDL 和 DML 脚本的分离 - Flyway

如何生成 Oracle 模式的整个 DDL(可编写脚本)?

DB2表结构DDL脚本导出

使用 Redbean PHP ORM 时,是不是必须在每个脚本中调用 R::freeze()?

ORM 谁可以动态生成脚本

如何在 oracle 中使用 get_ddl 从创建表脚本中忽略创建分段脚本?