6

我昨天一整天都在阅读有关 Hibernate 的各种文章/教程,尽管我对它的强大感到震惊,但我对它有一个主要关注点。

似乎标准做法是允许 Hibernate 为您设计/生成您的 DB 模式,这是一个令我窒息的新的和可怕的概念。从我阅读的教程中,您只需将一个新实体添加到您的hibernate.cfg.xml配置文件中,使用 注释任何您想要的 POJO @Entity,然后瞧——Hibernate 会为您创建表。虽然这很酷,但它让我想知道一些场景:

  • 如果你已经有一个 DB 模式并且 Hibernate 想要为你生成的那个不符合它怎么办?如果您有一个疯狂的 DBA 拒绝在预定义的(非 Hibernate)模式上让步怎么办?
  • 如果您有包含数万条记录的引用表(就像世界上所有的城市一样)怎么办?您是否必须实例化save()数以万计的唯一 POJO,或者是否有办法配置 Hibernate,以便它尊重而不覆盖表中已经存在的数据?
  • 如果你想对你的模式/表进行性能调优怎么办?这包括索引、规范化,超出 Hibernate 自动创建的内容?
  • 如果您想向表中添加约束或触发器怎么办?索引?

我想这的根源如下:

看起来 Hibernate 在您的数据库上创建并强制执行特定的模式/配置。我想知道这个议程将如何与我们的平台标准、我们的 DBA 理念以及我们对与 Hibernate 交互的表进行优化/调整的能力相冲突。

提前致谢。

4

9 回答 9

5

我认为您将过多的力量归因于休眠。

Hibernate 确实有一个可能会影响数据库实现的习语。

Hibernate 不会您生成模式,除非您要求它这样做。可以从现有模式开始并使用 Hibernate 将其映射到 Java 对象。但如果模式与 Hibernate 要求冲突,它可能是不可能的或最佳的。

如果 DBA 不让步——他们不应该让步——或者 Hibernate 不能适应你,那么你就有了答案:你不能使用 Hibernate。

您的 DBA 可能会同意,但您的应用程序可能会发现 Hibernate 为您生成的动态 SQL 不是您想要的。

幸运的是,这不是镇上唯一的游戏。

我不认为实现必须是全部或全部。如果使用简单的 JDBC 访问引用数据,有什么危害?

数据库设计考虑应该独立于 Hibernate。约束、触发器、规范化和索引应该由业务需求驱动,而不是您的中间件选择。

如果您没有实体对象模型,或者架构无法容纳它,那么您应该重新考虑 Hibernate。有直接的 JDBC、存储过程、Spring JDBC 和 iBatis 作为替代方案。

于 2012-06-21T16:38:23.760 回答
2

Hibernate 提供了一种将对象映射到表的默认方式——就像几个工具/库一样,为了简单起见,它倾向于约定而不是配置。

但是,如果您想以不同的方式将实体映射到数据库表,您可以显式告诉 Hibernate 这些是如何映射的(从简单的属性,例如更改表名,到重新定义相关实体之间的外键关系以及如何持久化) )。

如果您正确地执行此操作,则不需要实例化和保存现有数据,因为这将毫无意义 - 数据库已经以 Hibernate 理解的形式包含有关实体的信息。(考虑一下 - 加载然后立即保存实体应该始终是无操作的,因此可以完全跳过。)

所以你的问题的简短回答是“不”。如果你不关心设计表,你可以让 Hibernate 采用一个合理的默认值。如果你确实想明确地设计你的模式,你可以这样做,然后向 Hibernate 描述那个确切的模式。

于 2012-06-21T16:39:20.427 回答
2

作为长期在企业从事java和hibernate工作的人,我见过很少有项目使用这种能力。你会看到一些构建工具和其他东西可以做到这一点,但对于真正的企业应用程序,我从未见过。

大多数 DBA 不会让应用程序用户创建表。他们依靠特权用户来做这些事情,并且应用程序连接的用户将拥有数据的 r/w privs,而不是架构本身。

因此,您自己编写 SQL,并执行休眠映射以匹配。这并不意味着您的对象设计不会影响您的 SQL,但您仍应始终预先创建模式。

于 2012-06-21T16:45:56.997 回答
1

不可以。您可以使用休眠工具从现有数据库生成实体。

使用 Hibernate 有两种方法。如果你有优秀的 DBA 或数据库设计师,那么最好先设计好数据库,然后将其映射到 hibernate。另一方面,如果您没有 DBA 并且有优秀的开发人员,那么让 Hibernate 为您生成数据库。

Hibernate 背后的概念是映射数据库和对象。所以它被称为ORM(对象关系映射)工具。在这里
阅读对象关系阻抗。

于 2012-06-21T16:38:15.900 回答
0

这是快速原型或简单教程的首选方式,但远非任何生产应用程序的首选方式。我更喜欢独立设计数据库,使用脚本生成架构、表、视图、索引等,并将架构映射到实体。

只要映射找到数据库中的表和列,一切都很好。

一旦您的数据库中有数据并且架构必须更改,您无论如何都必须编写迁移脚本。您不能只是放弃所有内容并从头开始。这些教程是为从 Hibernate 开始的开发人员编写的,他们必须尽快发现 Hibernate,而无需处理复杂的 SQL 脚本。

于 2012-06-21T16:40:08.360 回答
0
  • 如果您已经有数据库架构怎么办...

我不知道你从哪里得到这样的印象。Hibernate 可以使用现有的模式。它非常灵活。

  • 如果您有参考表怎么办...

使关系 LAZY,它不会自动加载。只有更改的对象将被保存。

  • 如果你想进行性能调优怎么办......

只是不要使用生成的模式。这只是一个起点。您可以根据需要进行自定义。

  • 如果您想向表中添加约束或触发器怎么办?索引?

有的如上。

于 2012-06-21T16:42:22.910 回答
0

您可以将休眠与现有的数据库模式一起使用。您可以使用各种注释映射到现有的表和列,例如:

@Table(name = "dbschema.dbTable") - 应该放在你的类文件之前以映射它 @Column(name = "colName") - 映射一个列

只需确保使用此选项配置休眠:hibernate.hbm2ddl.auto=update

如果您将其设置为创建,它将创建架构,因此在您的情况下不要这样做。

于 2012-06-21T16:42:34.537 回答
0

适当时使用hibernate/jpa。设计应用程序时的一种常见做法是提取草稿并在需要(索引等)后手动更改它。但是,如果您将数据库布局从休眠方式更改为执行操作,这对您来说将是一件痛苦的事情。JPA 的许多优点将丢失。对于需要大量性能调整和完全控制的任务 - 只需使用 reguar jdbc。

于 2012-06-21T16:46:57.263 回答
0

一些答案:
A. 可以添加索引注释:见表注释。

B. 如果您有参考表,您可以选择延迟获取或急切获取(即 - 如果您的表代表一个人和他的书 - 是否加载一个没有书的人,或者加载他的书)

C. Hibernate 可以用于处理现有模式。使用该模式可能并不简单,但正如其他人所说,您应该仅根据业务需求设计 db,而不是根据框架约定

D。我想鼓励您也阅读 hibernate 在“幕后”所做的事情" - 它使用了大量的代理,这会损害性能,您必须清楚地了解会话的范围,以及一级和二级缓存的用法

. E. 遵循我在 D 节中所写的内容 - 使用触发器将导致您的数据库在休眠时“在后台”发生变化。考虑更新记录将在某个归档表中创建(使用触发器)条目的情况,并且假设该表也通过休眠进行注释
- 您的休眠缓存将不知道发生在应用程序范围之外的更改。

F. 声明我并不反对 Hibernate 对我来说很重要,但你不应该将它用于所有解决方案,这是我过去犯的一个错误。我现在使用 Spring-JDBC,我很高兴(对于我们的应用程序需要,很难使用 Hibernate,我假设我们只会在需要支持多个 DB 风格的情况下考虑这一点)。

于 2012-06-21T18:58:29.777 回答