3

我在我们目前在 SQL Server 上工作的应用程序中引入了一个 DAO 层,因为我需要将它移植到 Oracle。

我想使用 Hibernate 并编写一个工厂(或使用依赖注入)来根据部署配置选择正确的 DAO。在这种情况下,最佳实践是什么?我应该有两个具有不同 hibernate.cfg.xml 和 *.hbm.xml 文件的包并在我的工厂中相应地选择它们吗?我的 DAO 是否有可能在没有(太多)麻烦的情况下与两个 DBMS 一起正常工作?

4

4 回答 4

3

假设两者之间的表名和列相同,您应该可以使用相同的hbm.xml文件。但是,您肯定需要提供不同的 Hibernate 配置值 ( hibernate.cfg.xml),因为您需要将 Hibernate 的方言从 SQLServer 更改为 Oracle。

如果两者之间存在细微的名称差异,那么我将创建两组映射文件 - 每个数据库服务器一组 - 并将它们打包成单独的 JAR(例如yourproject-sqlserver-mappings.jaryourproject-oracle-mappings.jar),然后使用一个 JAR 或另一个部署应用程序,具体取决于环境。

于 2009-10-21T16:00:06.367 回答
3

不久前我为一个客户做了这个——在部署时,取决于文件中设置的属性,我使用 Antproduction.properties更改了文件hibernate.dialect中的属性(您可以使用任何 xml 转换器)。cfg然而,这只有在 Hibernate 代码是无缝的 btw 两个 DB 时才有效,即没有特定于 db 的函数调用等。HQL/JPAQL 有标准的函数调用,可以帮助解决这方面的问题UPPER(s)LENGTH(s)等等。

如果数据库实现必须不同,那么您必须执行@matt 建议的操作。

于 2009-10-21T17:12:18.463 回答
3

我开发了一个支持很多数据库(Oracle、Informix、SQL Server、MySQL)的应用程序。我们有一个配置文件和一组映射。我们使用 jndi 进行数据库连接,因此我们不必在应用程序中处理不同的连接 URL。当我们初始化 SessionFactory 时,我们有一个从底层连接推断数据库类型的方法。例如,通过 JNDI 手动获取连接,然后使用 connection.getMetaData().getDatabaseProductName() 找出数据库是什么。您还可以使用容器环境变量来显式设置它。然后使用 configuration.setProperty(Environment.DIALECT, deducedDialect) 设置方言并正常初始化 SessionFactory。

你必须处理的一些事情:

  • 主键生成。我们使用自定义版本的 TableGenerator 策略,因此我们有一个键表,其中包含表名和下一个键的列。这样,每个数据库都可以使用相同的策略,而不是 Oracle 中的序列、SQL Server 的原生数据库等。
  • 特定于数据库的功能。我们尽可能避免使用它们。Hibernate 方言处理最常见的方言。有时我们必须将我们自己的添加到我们的自定义方言类中,.eg 日期算术是非常不标准的,所以我们只需组成一个函数名称并将其映射到每个数据库的执行方式。
  • 模式生成 - 我们使用 Hibernate 模式生成类 - 它与方言一起为每种类型的数据库创建正确的 DDL 并强制数据库匹配映射。您必须了解每个数据库的关键字,例如不要尝试在 Oracle 中使用 USER 表(USERS 可以),或在 MySQL 中使用 TRANSLATION 表。
于 2009-10-21T18:46:06.730 回答
3

这里有一张表映射了 Oracle 和 SQLServer 之间的差异:http: //psoug.org/reference/sqlserver.html

在我看来,最大的陷阱是:1)日期。功能和机制完全不同。您将不得不为每个数据库使用不同的代码。2) 密钥生成——Oracle 和 SQLServer 使用不同的机制,如果你试图通过拥有自己的密钥表来完全避免“本机”生成——那么,你只是完全序列化了所有“插入”。对性能不好。3)并发/锁定有点不同。对于每个数据库,性能敏感的部分代码可能会有所不同。4) Oracle 区分大小写,SQLServer 不区分。你需要小心。

还有更多 :) 编写将在两个数据库上运行的 SQL 代码具有挑战性。有时让它变得更快似乎几乎是不可能的。

于 2009-10-22T03:10:08.940 回答