代码之家  ›  专栏  ›  技术社区  ›  Manrico Corazzi

在Oracle和SQLServer上休眠

  •  2
  • Manrico Corazzi  · 技术社区  · 15 年前

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

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

    4 回复  |  直到 15 年前
        1
  •  3
  •   matt b    15 年前

    假设表名和列在这两者之间是相同的,您应该能够使用相同的名称 hbm.xml 文件夹。但是,您肯定需要提供不同的Hibernate配置值( hibernate.cfg.xml

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

        2
  •  3
  •   non sequitor    15 年前

    production.properties 我把文件换掉了 hibernate.dialect cfg 文件使用Ant(您可以使用任何xml转换器)。但是,只有当Hibernate代码与两个DBs无缝连接时,这才有效,即没有特定于db的函数调用等。HQL/JPAQL有标准函数调用,在这方面有帮助 UPPER(s) , LENGTH(s)

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

        3
  •  3
  •   Brian Deterling    15 年前

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

    一些你必须处理的事情:

    • 主键生成。我们使用了TableGenerator策略的定制版本,所以我们有一个键表,表名列和下一个键列。这样,每个数据库都可以使用相同的策略,而不是Oracle中的顺序、SQL Server的本机等。
    • 特定于数据库的函数。我们尽可能避免它们。冬眠方言处理最常见的方言。有时我们不得不将自己的添加到自定义方言类中。日期算法是非常不标准的,所以我们只需要构造一个函数名,并将其映射到每个数据库的执行方式。
    • 模式生成—我们使用Hibernate模式生成类—它与方言一起为每种类型的数据库创建正确的DDL,并强制数据库匹配映射。您必须了解每个数据库的关键字,例如,不要尝试在Oracle中使用用户表(用户可以使用),或在MySQL中使用翻译表。
        4
  •  3
  •   user130770    15 年前

    此处有一个表映射了Oracle和SQLServer之间的差异: http://psoug.org/reference/sqlserver.html

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

    还有很多:) 编写将在两个DBs上运行的SQL代码是一项挑战。有时,让它变快几乎是不可能的。