简体   繁体   English

通过动态更改XSD与数据库数据生成XML

[英]Generating XML with DB data through dynamically changing XSD

Considering an example for a shop 考虑商店的例子

I have an XSD for a shop, and a number of tables having data relating to inventory, records etc. I have a DB-file specifying where the data related to the XSD lies in the tables. 我有一家商店的XSD,还有许多具有与库存,记录等有关的数据的表。我有一个DB文件,用于指定与XSD有关的数据在表中的位置。 I need to refer this file and XSD to create XML records for multiple shops 我需要引用此文件和XSD来为多个商店创建XML记录

My current solution is to generate JPA entities using HyperJAXB through the XSD and read the data to generate the XML's but I need to make code changes every time the DB-file and XSD have changes. 我当前的解决方案是通过XSD使用HyperJAXB生成JPA实体,并读取数据以生成XML,但是每次DB文件和XSD发生更改时,我都需要进行代码更改。

Is it possible to accommodate these changes at runtime whilst using JPA because the DB structure is complex. 因为DB结构很复杂,使用JPA时是否可以在运行时适应这些更改。 How can I minimize the effort required to accommodate changes if not doing at runtime. 如果在运行时不做更改,我如何最大程度地减少适应更改所需的精力。

Ok based off of your current use case I really think using a product like SSIS which specializes in ETL processes could do this the most efficiently. 好的,根据您当前的用例,我真的认为使用像SSIS这样的产品专门研究ETL流程可以最有效地做到这一点。 I am fairly certain there is even a way to avoid translation by having SSIS create the xml. 我相当确定,甚至可以通过让SSIS创建xml来避免翻译。

However, if you want to keep doing the process in java I would recommend moving away from JPA due to an object representing the database. 但是,如果您想继续用Java进行处理,由于对象代表数据库,我建议您远离JPA。 This means you will always have coding changes when the database schema gets updated. 这意味着在更新数据库架构时,您将始终具有编码更改。 I would take a step back and leverage more raw SQL over a JdbcTemplate. 我会退后一步,在JdbcTemplate上利用更多原始SQL。 You can get a fairly generic process by leveraging a few SQL commands: 您可以利用一些SQL命令来获得相当通用的过程:

SHOW tables

then you can get tall results for each table 那么你可以在每张桌子上获得很高的结果

SELECT * FROM table

This will return a result set which could be turned into XML for each table with a method like... 这将返回一个结果集,该结果集可以使用以下方法转换为每个表的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;
}

This should let you print every table as XML, if you need it to be hierarchy based there is obviously a bit more work involved, but this would enable you to create a generic process that can export all database tables as xml. 这应该让您将每个表都打印为XML,如果您需要将其作为基于层次结构的表,则显然会涉及更多的工作,但这将使您能够创建一个通用过程,该过程可以将所有数据库表导出为xml。

Update #1: 更新#1:

Based off some conversations with my co-workers the best practices we follow to helping to manage database migrations still has a lot of manual work, but here are some of the mitigation steps we take from our practices. 根据与同事的交谈,我们在帮助管理数据库迁移方面遵循的最佳实践仍然需要大量的人工工作,但这是我们从实践中采取的一些缓解措施。

We use schema versioning with either liquibase or flyway to manage schema changes in our database across multiple environments. 我们将模式版本与liquibase或flyway一起使用,以在多个环境中管理数据库中的模式更改。 This can guarantee that regardless of environment the schema will be correct. 这样可以保证无论环境如何,架构都是正确的。

We also generate the schema from hibernate and use schema comparison tools (these tend to be database specific) to validate that the hibernate model will be identical to the database model. 我们还从休眠模式生成模式,并使用模式比较工具(这些模式比较特定于数据库)来验证休眠模式是否与数据库模型相同。 This operation is done by our Jenkins build server typically to ensure every build is compatible with the desired database schema version. 此操作通常由我们的Jenkins构建服务器完成,以确保每个构建都与所需的数据库架构版本兼容。

Hibernate configuration is also set to hibernate.hbm2ddl.auto=validate to ensure compatibility with the database tables on start up. Hibernate配置也设置为hibernate.hbm2ddl.auto = validate以确保在启动时与数据库表兼容。

Our local application uses the Junit framework and creates an instance of hibernate running on derby for database style unit / integration testing. 我们的本地应用程序使用Junit框架并创建一个在derby上运行的hibernate实例,以进行数据库样式单元/集成测试。 These tests ensure that previous compatibility should not be broken. 这些测试确保了先前的兼容性不会被破坏。

When a database is shared between multiple java applications the JPA layer is occasionally shared across all of these applications and multiple groups will be responsible for that particular code base. 当数据库在多个Java应用程序之间共享时,JPA层有时会在所有这些应用程序之间共享,并且多个组将负责该特定的代码库。 This practice helps keep all applications in sync with database changes and leveraging the same access patterns. 这种做法有助于使所有应用程序与数据库更改保持同步,并利用相同的访问模式。 Typically a host of generic named queries are also created to avoid application teams needing to create custom queries. 通常,还会创建许多通用的命名查询,以避免应用程序团队需要创建自定义查询。

Unfortunately we have not come across a silver bullet that could automatically evaluate a database schema change and update the application. 不幸的是,我们还没有找到可以自动评估数据库架构更改并更新应用程序的灵丹妙药。 Currently the process of driving database changes from application JPA changes isn't accepted due to generation process of hibernate not being ideal for every database. 当前,由于休眠的生成过程并不是每个数据库的理想选择,因此不接受从应用程序JPA更改驱动数据库更改的过程。 As well as a lot of the risks with the hibernate auto update the schema feature which isn't a production grade feature. 休眠自动更新架构功能(这不是生产级功能)还有很多风险。

Well that turned out to be quite... wordy, but I hope I gave you some insight into your problem. 好吧,事实证明……罗y,但我希望我对您的问题有所了解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM