Hibernate.org Community Documentation

- 上一页
- 下一页

## 第 28 章 数据库移植性考量

## 28.1. 移植性基础

Hibernate（实际上是整个 Object/Relational Mapping）的一个卖点是数据库的移植性。这意味着内部的 IT 用户可以改变数据库供应商，或者可部署的应用程序/框架使用 Hibernate 来同时使用多个数据库产品。不考虑具体的应用情景，这里的基本概念是 Hibernate 可帮助你运行多种数据库而无需修改你的代码，理想情况下甚至不用修改映射元数据。

## 28.2. Dialect

Hibernate 的移植性的首要问题是方言（dialect），也就是 `org.hibernate.dialect.Dialect` 合约的具体实例。方言封装了 Hibernate 和特定数据库通讯以完成某些任务如获取序列值或构建 SELECT 查询等的所有差异。Hibernate 捆绑了用于许多最常用的数据库的方言。如果你发现自己使用的数据库不在其中，编写自定义的方言也不是很困难的事情。

## 28.3. 方言的使用

最开始，Hibernate 总是要求用户指定所使用的方言（dialect）。在用户希望同时使用多个数据库时就会出现问题。通常这要求用户配置 Hibernate 方言或者定义自己设置这个值的方法。

从版本 3.2 开始，Hibernate 引入了方言的自动检测，它基于从该数据库的 `java.sql.Connection` 上获得的 `java.sql.DatabaseMetaData`。这是一个更好的方案，但它局限于 Hibernate 已知的数据库且无法进行配置和覆盖。

Starting with version 3.3, Hibernate has a fare more powerful way to automatically determine which dialect to should be used by relying on a series of delegates which implement the `org.hibernate.dialect.resolver.DialectResolver` which defines only a single method:

    public Dialect resolveDialect(DatabaseMetaData metaData) throws JDBCConnectionException

The basic contract here is that if the resolver 'understands' the given database metadata then it returns the corresponding Dialect; if not it returns null and the process continues to the next resolver. The signature also identifies `org.hibernate.exception.JDBCConnectionException` as possibly being thrown. A JDBCConnectionException here is interpreted to imply a "non transient" (aka non-recoverable) connection problem and is used to indicate an immediate stop to resolution attempts. All other exceptions result in a warning and continuing on to the next resolver.

这些解析者最棒的功能是用户也可以注册自定义的解析者，它们将在内置的解析者之前被调用。在许多情况下这可能很有用：它可以轻易地集成内置方言之外的方言的自动检测；它让你可以使用自定义的方言等。要注册一个或多个解析者，只要用 'hibernate.dialect_resolvers' 配置设置指定它们（由逗号、制表符或空格隔开）就可以了（请参考 `org.hibernate.cfg.Environment` 上的 `DIALECT_RESOLVERS`）。

## 28.4. 标识符的生成

When considering portability between databases, another important decision is selecting the identifier generation stratagy you want to use. Originally Hibernate provided the native generator for this purpose, which was intended to select between a sequence, identity, or table strategy depending on the capability of the underlying database. However, an insidious implication of this approach comes about when targtetting some databases which support identity generation and some which do not. identity generation relies on the SQL definition of an IDENTITY (or auto-increment) column to manage the identifier value; it is what is known as a post-insert generation strategy becauase the insert must actually happen before we can know the identifier value. Because Hibernate relies on this identifier value to uniquely reference entities within a persistence context it must then issue the insert immediately when the users requests the entitiy be associated with the session (like via save() e.g.) regardless of current transactional semantics.

## 注意

Hibernate was changed slightly once the implication of this was better understood so that the insert is delayed in cases where that is feasible.

The underlying issue is that the actual semanctics of the application itself changes in these cases.

Starting with version 3.2.3, Hibernate comes with a set of enhanced identifier generators targetting portability in a much different way.

## 注意

There are specifically 2 bundled enhancedgenerators:

- `org.hibernate.id.enhanced.SequenceStyleGenerator`

- `org.hibernate.id.enhanced.TableGenerator`

The idea behind these generators is to port the actual semantics of the identifer value generation to the different databases. For example, the `org.hibernate.id.enhanced.SequenceStyleGenerator` mimics the behavior of a sequence on databases which do not support sequences by using a table.

## 28.5. 数据库函数

## 警告

这是 Hibernate 需要提高的一个领域。从可移植性来说，这个功能可以很好地处理 HQL 的内容，但在其他方面就有所欠缺。

用户可以以多种方式引用 SQL 函数。然而，不是所有的数据库都支持相同的函数集。Hibernate 提供了一种映射逻辑函数名到代理的方法，这个代理知道如何解析特定的函数，甚至可能使用完全不同的物理函数调用。

## 重要

从技术上来讲，这个函数注册是通过 `org.hibernate.dialect.function.SQLFunctionRegistry` 类进行处理的，它的目的是允许用户提供自定义的函数定义而无需提供自定义的方言。这种特殊的行为目前还未全部开发完毕。

其中一些功能已经实现，如用户可以在程序里用 `org.hibernate.cfg.Configuration` 注册函数且这些函数可被 HQL 识别。

## 28.6. 类型映射

本节内容仍未完成...

版权 © 2004 Red Hat, Inc.

- 上一页第 27 章 最佳实践（Best Practices）
- 上一级
- 起始页
- 下一页参考资料