【问题标题】:Hibernate : schema export in real world?Hibernate:现实世界中的模式导出?
【发布时间】:2010-12-30 09:32:35
【问题描述】:

我对在我的下一个项目中完全使用模式导出感到好奇。我认为这是一种真正处理对象而不是底层数据库的非常有用的方法。只需创建和注释模型,然后将其导出。

但是从先创建表然后创建模型对象的习惯来看,我对完全使用模式导出存有疑虑。这主要是因为我没有真正深入研究休眠。但是我仍然很好奇这个区域列表在使用模式导出时是否会成为问题。请分享您的经验..

  1. 表之间的关系
  2. 代理/复合主键支持
  3. 当我只想从多个模型中导出一些模型时,重新导出将重新创建所有数据库?
  4. 其他我暂时想不到

谢谢

【问题讨论】:

    标签: java hibernate


    【解决方案1】:

    我个人不喜欢导出 DDL,原因如下。

    1. 数据库可能是应用程序中最关键的基础设施之一,相信 DDL 生成到休眠意味着您必须检查由休眠生成的所有 DDL 以确保一切正常,检查这个过程和编写 DDL 一样耗时。

    2. 当需要发布应用程序的新版本时,您将拥有一个现有数据库,因此您可能希望使用 alter 语句,并拥有一个 upgrade-to-version-x.sql 脚本修改现有数据库以使新数据库与新版本一起使用。此时,自动 DDL 生成对您没有帮助,因为带注释的 hibernate 类只会导致生成 CREATE 语句而不是 ALTER DDL 语句。

    3. Hibernate/JPA 注释分为逻辑和物理两类。逻辑注解是@Entity,物理注解是@Table、@Columns ...等。在物理注解上定义的属性不足以精确控制为SQL生成的数据库类型。例如,假设您有一个包含 Date 的列并且您在其上使用 @Column,@Temporal 注释,通常有多个数据库数据类型适合,相信 hibernate 选择默认值可能不是明智之举。

    4. 总是有一些特定于数据库的最佳实践,hibernate 不会知道,但 DBA 会知道。例如,如果要创建索引,则无法在 hibernate 注释中指定,或者指定要创建的索引类型,例如 B-Tree、Bitmap ... 等。如果 JPA/Hibernate 注释已增强以允许您指定可以在特定于数据库的 DDL 中指定的所有选项,那么注释将比 SQL 更复杂,因为 SQL 是构建得非常好的领域特定语言,并且注释永远不会像 SQL DDL 一样好,他们会更罗嗦。你最终所做的只是在不降低复杂性的情况下转移复杂性。想想你遇到的所有基于 XML 的配置语言,最终会增加越来越多的复杂性,直到类似于真正的编程语言,包含基于 xml 的循环、if 语句、变量......等等

    5. 如果应用程序发展壮大并且是具有大量数据的成功业务应用程序,您最终将需要聘请 DBA 来调整、优化、镜像数据库……等等 DB​​A 将了解其数据库的最佳实践但不一定/可能不知道 Hibernate,这将使 DBA 的生活变得更加复杂。 DBA 可以对数据库进行许多不影响基于休眠的 java 代码的更改,您是否真的希望 DBA 更改休眠代码以更改数据库设置。一旦 DBA 更改了数据库设置,现在您就有了两个版本的数据库,一个是从休眠中导出的版本,另一个是生产版本,哪个是真实的?

    6. 数据库设计最佳实践和面向对象设计最佳实践并不相同。从对象设计数据库可能意味着一个伟大的 OO 设计,但不是一个伟大的 DB 设计,首先设计 DB,然后是 Hibernate 面向对象的代码可能意味着一个伟大的 DB 设计,但不是一个伟大的 hibernate / OO 设计。从哲学上讲,我更喜欢手工编写 DDL 以将自己置于数据库设计模式而不是 OO 设计模式。在一个成功的应用程序中,数据库设计可能比休眠时间长很多年。仅仅因为 hibernate 是今天唯一与数据库通信的东西,并不意味着它将成为将来唯一与数据库通信的东西。因此,我倾向于使用数据库设计最佳实践而不是 OO 最佳实践来优化数据库设计。

    7. Hibernate / ORM 是泄漏抽象,无法向开发人员隐藏您正在处理 SQL 数据库的事实,如果您的开发人员不太了解 SQL,他们可能会在使数据库成为瓶颈的方法。培训人员使用 Hibernate 的个人经验告诉我,您必须更好地了解 SQL 才能有效地使用 Hibernate。您需要能够检查 HQL 或其他一些对象查询语言并在心理上转换为 SQL。您将需要知道何时可以映射关系并遍历它们与使用报表查询。您将需要了解为什么在查询中丢失 JOIN 是一个这样的问题。我是 ORM/Hibernate 的忠实粉丝,我可以有效地使用它,但我发现许多开发人员低估了使用 ORM 工具(如 hibernate)的复杂性。

    8. 唯一可能导致我导出 Schema 的例外情况是,如果我正在编写一个废弃原型并且我不太了解特定于数据库的 DDL。但是我还没有遇到过很多没有突然变成永久性的丢弃原型。

    这些是我反对从 Hibernate 注释生成 DDL 的原因。我希望其他人能说出他们的想法和经验。

    【讨论】:

    • 感谢您分享您的经验。我对您的陈述“数据库设计最佳实践和面向对象设计最佳实践不一样”有点不清楚。我有一个简单的想法,首先是数据库设计或域模型设计,每个表最终都会有自己的模型。 “报告查询”是指存储过程吗?总的来说,我现在非常确定完全依赖模式导出对我来说可能不再是一个好主意。再次感谢!
    • 面向对象设计和数据库设计不是一回事 数据库设计的某些方面在面向对象设计中没有等价物,而面向对象设计原则在面向对象设计中没有等价物数据库设计。虽然您可以设计一个很棒的一对一映射,但 jpa/hibernate 的许多功能仍然必须使映射更好,远远超过我可以向您展示的示例。报表查询不是存储过程,它们是休眠的一个特性。查看 Java Persistence with Hibernate 2nd edition 了解完整详情。
    • 非常感谢您的指点。新年快乐,有美好的一天。 =)
    • 也许是迟到的评论,但我发现 liquibase (liquibase.org) 是管理 SQL 架构而不是休眠本身的好工具。
    • flwaydb.org 是另一个工具,它是 liquibase 的一个很好的替代品,我目前在我的项目中使用 flyway
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 2010-10-06
    • 2010-09-15
    • 1970-01-01
    • 2014-02-03
    相关资源
    最近更新 更多