【问题标题】:Hibernate on Oracle AND SQLServer在 Oracle 和 SQL Server 上休眠
【发布时间】:2010-12-08 18:37:51
【问题描述】:

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

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

【问题讨论】:

标签: java sql-server oracle hibernate multiple-databases


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      你必须处理的一些事情:

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

      【讨论】:

        【解决方案4】:

        这里有一张表映射Oracle和SQLServer的区别:http://psoug.org/reference/sqlserver.html

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-03-26
          • 2012-12-28
          • 1970-01-01
          • 2013-02-24
          • 1970-01-01
          • 2017-01-16
          • 2012-04-10
          相关资源
          最近更新 更多