2009-10-21 127 views
2

我在我们的应用程序当前正在使用SQL Server中引入DAO层,因为我需要将它移植到Oracle。Oracle和SQLServer上的休眠

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

+0

DAO代表数据访问对象。欲了解更多信息:http://en.wikipedia.org/wiki/Data_access_object – wassimans 2012-06-26 20:01:03

回答

3

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

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

3

我之前为客户做了这个 - 部署取决于在production.properties文件中设置的属性,我使用Ant(您可以使用任何xml转换器)更改文件中的hibernate.dialect文件。但是,如果Hibernate代码是无缝这只会工作的BTW两数据块,即没有具体的DB函数调用等HQL/JPAQL有标准的函数调用帮助离子这方面像UPPER(s)LENGTH(s)

如果DB实现必须必然会有所不同,那么你必须做一些像@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表。
3

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

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

还有很多:) 编写将在两个数据库上运行的SQL代码具有挑战性。加快速度似乎有时几乎是不可能的。