2011-11-24 96 views
3

我們目前有以下任務,我正在努力尋找我認爲應該在哪裏的地方。Hibernate寫入XML數據庫

datamodel通過Hibernate存儲在MySQL中。一切工作正常,產品出貨。

對於計劃的未來版本,儘管需要更改數據模型。我們還不知道發生了什麼變化,發生了多大的變化,但我們確實知道客戶數據庫必須相應更新。

這很可能會再次對未來的版本中,這使我分手問題的一個未來版本發生:

  • 是否合理通過轉換現有的數據庫內容來解決這個問題,通過他們出口到一個XML文件,基於它們已經創建的Hibernate版本,然後在用更新的Hibernate版本重寫數據庫內容之前更新內容(使用XSLT的f.ex.)?

我可以看到這種方法的優點如下:

  • 我們必須一次寫一個XSLT新版本。
  • 我們可以很容易地將其應用於所有客戶 - 甚至是自動化的。
  • 通過鏈接相應的XSLT,我們可以輕鬆地將數據庫內容從版本X轉換爲版本Y,即使存在多個版本。

但是,假設採用這種方法,實際的問題是我們不希望編寫額外的代碼來生成相應的XML文件。最好,我想使用一個數據庫,它的內容存儲在一個XML文件中,並提供一個JDBC接口。有沒有人知道如何以最小的努力實現這一目標?

工作流程我心目中是以下幾點:

  • 從版本X.使用Hibernate的數據模型創建兩個數據庫連接,一個MySQL數據庫,一個XML DB。從第一個中讀出所有內容,將其轉儲到後面(這可能需要一些自定義代碼)
  • 編寫XSLT,在XML DB的XML文件上執行它。
  • 使用版本Y的Hibernate數據模型創建兩個數據庫連接,一個連接MySQL DB,一個連接XML DB。從XML讀出所有內容並將其轉儲回MySQL。

可行嗎?有沒有更好的方法來解決這個問題?我在哪裏可以找到一個支持JDBC的XML數據庫?

回答

1

一個簡單的解決方案可以是一個的mysqldump --xml(http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_xml),其產生像數據:

<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<database name="world"> 
    <table_data name="City"> 
    <row> 
     <field name="ID">1</field> 
     <field name="Name">Kabul</field> 
     <field name="CountryCode">AFG</field> 
     <field name="District">Kabol</field> 
     <field name="Population">1780000</field> 
    </row> 

然後可以轉換該數據,並使用「LOAD XML INFILE再次裝入表的每個表'http://dev.mysql.com/doc/refman/5.5/en/load-xml.html

作爲替代方案,我聽說有很好的結果有些同事Liquibase:數據庫重構工具。這允許您使用http://www.liquibase.org/manual/refactoring_commands中列出的重構命令以描述性方式編寫數據庫遷移腳本。

例如:

<databaseChangeLog> 
    <changeSet id="1" author="greyfairer> 
    <addLookupTable 
     existingTableName="address" existingColumnName="state" 
     newTableName="state" newColumnName="abbreviation" 
     constraintName="fk_address_state" 
    /> 

Liquibase還跟蹤那名曾經在一個專門的變更表應用的所有變更集。因此,如果您的產品版本2中應用了變更集2a和2b,而版本3中變更了3a和3b,則Liquibase可以檢測到例如如果從版本1升級,則需要應用全部4個版本,並且版本2只需要3a和3b,因爲2a和2b已經在變更集表中。當然,這些解決方案並不能反映你的領域模型,但有時在進行這樣的遷移時,用數據庫術語而不是域名術語工作更容易。

+0

謝謝。這幾乎是我所期待的。還不完全,但肯定值得進一步探討。 – Frank

1

我認爲這對XML數據庫(如eXist)來實現JDBC沒有任何意義,因爲JDBC直接基於處理SQL和關係模型。此外,我不確定我看到XML的計劃好處是什麼; XSLT是XML內容的好轉換語言。但是在這種情況下,您最多隻能使用關係數據的XML包裝,而不是樹形深層嵌套的文本數據。 因此,您可能最好是編寫Java代碼來逐行進行更改。 這是一個相當普遍的做法。

您當然可以使用XML或JSON作爲中間存儲/緩衝格式,即句柄導入和導出。但是,中間處理不一定會從XSLT或臨時數據庫中受益。

+0

我特別尋找一種可以很好地擴展的方法。你如何處理這個問題,當它發生在幾個版本之後?鏈接XSLT很容易,但是使用不同版本的相同庫的不同Java程序。我不明白這樣做會如何工作? – Frank

+0

通常新的轉換僅僅是我見過的例子的附加類 - 甚至只是一個巨大的文件,帶有各種switch語句。不優雅,但取決於變化的數量,可行。從這個角度來看,我明白爲什麼一組XSLT看起來是個不錯的選擇。 – StaxMan

0

實現這一點的更好方法是不使用Hibernate IMO。

我們有一個使用nHibernate和SqlServer的解決方案,因此您的解決方案將有所不同,但我相信相關工具可以應用於實現相同的目標。

要從R1升級到R1.1,我們需要使用nHibernate映射文件(比如db1.1)將新模式生成到空的「構建」數據庫中。然後,我們將獲取當前版本(db1.0)的副本,並使用db架構工具(我們使用DbGhost)然後將db1.0升級到db1.1。

DbGhost(和其他類似工具)將自動添加非空添加和新表,併爲每批批量更改的自定義sql提供注入點。

它工作了一個夢想,並在我們的多開發人員,多功能環境中工作得很好。一個真正的好處是,對於最終版本來說,DbGhost調用可以被改變成產生一個概括所有chnage的升級scipt。

希望它有幫助。