2011-11-24 83 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。

希望它有帮助。