Oracle和SQLServer上的Hibernate

时间:2009-10-21 15:51:10

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

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

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

4 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:3)

我在一段时间内为客户端做了这个 - 在部署时,取决于production.properties文件中设置的属性,我使用Ant更改了hibernate.dialect文件中的cfg可以使用任何xml变换器)。但是,这只有在Hibernate代码是无缝的两个数据库时才有效,即没有特定于数据库的函数调用等.HQL / JPAQL具有标准函数调用,可以帮助实现UPPER(s)LENGTH(s)等。< / p>

如果db实现必须不同,那么你必须做一些像@matt建议的那样。

答案 2 :(得分: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表。

答案 3 :(得分:3)

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

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

还有很多:) 编写将在两个DB上运行的SQL代码具有挑战性。快速制作似乎几乎不可能。