通过动态更改XSD,使用DB数据生成XML

时间:2016-05-12 11:44:00

标签: java xml jpa jaxb hyperjaxb

考虑一个商店的例子

我有一个商店的XSD,以及一些包含库存,记录等数据的表。我有一个DB文件,指定与XSD相关的数据位于表中的位置。我需要引用这个文件和XSD来为多个商店创建XML记录

我目前的解决方案是通过XSD使用HyperJAXB生成JPA实体并读取数据以生成XML,但每次DB文件和XSD发生更改时我都需要更改代码。

使用JPA时是否可以在运行时适应这些更改,因为DB结构很复杂。如果不在运行时进行更改,如何最小化容纳更改所需的工作量。

1 个答案:

答案 0 :(得分:0)

根据您当前的使用案例,我真的认为使用像SSIS这样专门从事ETL流程的产品可以最有效地完成这项工作。我相当肯定甚至有一种方法可以通过让SSIS创建xml来避免翻译。

但是,如果你想继续在java中进行这个过程,我会建议由于代表数据库的对象而放弃JPA。这意味着当数据库模式更新时,您将始终进行编码更改。我会退后一步,在JdbcTemplate上利用更多的原始SQL。您可以通过利用一些SQL命令来获得相当通用的过程:

SHOW tables

然后你可以获得每个表的高结果

SELECT * FROM table

这将返回一个结果集,可以使用类似......

的方法将每个表转换为XML
public static Document toDocument(ResultSet rs) throws ParserConfigurationException, SQLException  {
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   DocumentBuilder builder = factory.newDocumentBuilder();
   Document doc = builder.newDocument();

   Element results = doc.createElement("Results");
   doc.appendChild(results);

   ResultSetMetaData rsmd = rs.getMetaData();
   int colCount = rsmd.getColumnCount();

   while (rs.next()) {
      Element row = doc.createElement("Row");
      results.appendChild(row);

      for (int i = 1; i <= colCount; i++)   {
         String columnName = rsmd.getColumnName(i);
         Object value = rs.getObject(i);

         Element node = doc.createElement(columnName);
         node.appendChild(doc.createTextNode(value.toString()));
         row.appendChild(node);
      }
  }
   return doc;
}

这应该允许您将每个表打印为XML,如果您需要它是基于层次结构的,显然会涉及更多工作,但这将使您能够创建一个可以将所有数据库表导出为xml的通用流程。 / p>

更新#1:

根据与我的同事的一些对话,我们遵循的帮助管理数据库迁移的最佳实践仍然需要大量的手动工作,但这里是我们从实践中采取的一些缓解措施。

我们使用liquibase或flyway的架构版本控制来管理跨多个环境的数据库中的架构更改。这可以保证无论环境如何,架构都是正确的。

我们还从hibernate生成模式,并使用模式比较工具(这些工具往往是特定于数据库)来验证hibernate模型是否与数据库模型相同。此操作通常由我们的Jenkins构建服务器完成,以确保每个构建都与所需的数据库模式版本兼容。

Hibernate配置也设置为hibernate.hbm2ddl.auto = validate,以确保在启动时与数据库表兼容。

我们的本地应用程序使用Junit框架并创建一个在derby上运行的hibernate实例,用于数据库样式单元/集成测试。这些测试确保不会破坏以前的兼容性。

当在多个Java应用程序之间共享数据库时,偶尔会在所有这些应用程序中共享JPA层,并且多个组将负责该特定代码库。此做法有助于使所有应用程序与数据库更改保持同步,并利用相同的访问模式。通常还会创建一系列通用命名查询,以避免应用程序团队需要创建自定义查询。

不幸的是,我们没有遇到可以自动评估数据库架构更改并更新应用程序的银弹。目前,由于hibernate的生成过程对于每个数据库都不是理想的,因此从应用程序JPA更改驱动数据库更改的过程是不被接受的。除了hibernate自动更新的许多风险之外,架构功能不是生产等级功能。

结果证明这很......罗嗦,但我希望我能帮助你解决一下你的问题。