2009-10-21 128 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代碼具有挑戰性。加快速度似乎有時幾乎是不可能的。