【问题标题】:Retrive data from XML in Java and insert data in Oracle在 Java 中从 XML 中检索数据并在 Oracle 中插入数据
【发布时间】:2019-09-13 16:27:14
【问题描述】:

我在 Java 中使用 JAXB Unmarshaler 将数据从 XML 检索到 Java 对象中,效果很好。

下面是我的代码:

import java.io.File;
import java.io.FileNotFoundException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;    

public class FRDDbImportWorkflow {


     public static void main(String...args) throws FileNotFoundException {

          File xmlFile = new File("//home/tr.xml");       

          try {             

              JAXBContext jaxbContext  = JAXBContext.newInstance(FRD115Type.class);

              Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

              JAXBElement<FRD115Type> jaxbElement = (JAXBElement<Fd115Type>) jaxbUnmarshaller
                        .unmarshal(new StreamSource(xmlFile), Fd115Type.class);

              FRD115Type obj = jaxbElement.getValue();

              System.out.println(obj.getRptHdr().getEnvText()); 
           } catch (JAXBException e) {
               e.printStackTrace();
       }

    }

}

现在我想创建另一个 java 类,它将这些数据插入到 Oracle 表中。由于我在 xml 文件中有许多 xml 元素,那么我是否需要为所有这些元素创建 get method 以从 xml 中检索数据然后插入到 Oracle 中?

除了为所有这些 xml 元素创建 get method 之外,还有其他解析器技术吗?

我也不确定如何将此 xml 数据插入 Oracle。我在 Oracle 中创建了下表:

CREATE TABLE
    IMPORT_XML
    (
        fd115 VARCHAR2(180),
        RPTHDR VARCHAR2(180),
        EXCHNAM VARCHAR2(50),
        ENVTEXT VARCHAR2(20),
        RPTCOD VARCHAR2(20),
        RPTNAM VARCHAR2(180),
        RPTFLEXKEY VARCHAR2(180),
        MEMBID VARCHAR2(50),
        MEMBLGLNAM VARCHAR2(80),
        RPTPRNTEFFDAT DATE,
        RPTPRNTEFFTIM VARCHAR2(50),
        RPTPRNTRUNDAT DATE,
        fd115GRP VARCHAR2(180),
        fd115KEYGRP VARCHAR2(180),
        PARTICIPANTGRP VARCHAR2(180),
        PARTICIPANT VARCHAR2(50),
        PARTLNGNAME VARCHAR2(50),
        fd115GRP1 VARCHAR2(180),
        fd115KEYGRP1 VARCHAR2(180),
        BUSINESSUNITGRP VARCHAR2(180),
        BUSINESSUNIT VARCHAR2(180),
        BUSUNTLNGNAME VARCHAR2(50),
        BUSINESSUNITID NUMBER(30,9),
        fd115GRP2 VARCHAR2(180),
        fd115KEYGRP2 VARCHAR2(180),
        USER_NAME VARCHAR2(50),
        USERNUMERICID NUMBER(30,9),
        fd115REC1 VARCHAR2(180),
        USRGROUP VARCHAR2(50),
        USER_LEVEL VARCHAR2(10),
        LOGNAM VARCHAR2(50),
        ISUSFLG NUMBER(30,9),
        EFFSTATUS NUMBER(30,9),
        DELPROTECTED VARCHAR2(10),
        ENABLEPROPRIETARYACCT VARCHAR2(10),
        ENABLEAGENCYACCT VARCHAR2(10),
        ENABLEMARKETMAKINGACCT VARCHAR2(10),
        ENABLEBESTACCT VARCHAR2(10),
        ENABLERISKLESSPRINCIPALACCT VARCHAR2(10),
        MAXORDERVALUE VARCHAR2(100),
        MAXORDRQTY VARCHAR2(100),
        SETTLACCT NUMBER(30,9),
        SETTLLOCAT VARCHAR2(50),
        fd115GRP3 VARCHAR2(180),
        fd115KEYGRP3 VARCHAR2(180),
        MKTGRPNAM VARCHAR2(50),
        fd115REC2 VARCHAR2(180),
        ENTROLE VARCHAR2(50),
        fd115GRP4 VARCHAR2(180),
        TESTYPE NUMBER(30,9),
        TESELIGIBILITY NUMBER(30,9)
    );

【问题讨论】:

  • 您的 XML 似乎无效,因为它缺少 &lt;/fd115Grp&gt;&lt;/fd115Grp1&gt; 结束标记。
  • 抱歉,我没有将完整的 xml 放置为它有点大..你想要完整的 xml 文件吗?
  • 不,最好是 minimal reproducible example,它只有 10-20 个数据点,但代表您的数据(并且是有效的 XML),这样我们就不必处​​理巨大的文档(但您的数据大于 4000 字节,因此需要作为 CLOB 传递)但您可以在其中推断答案中使用的技术并将其应用于您的(更大的)数据集。
  • 也不清楚表中的某些列(例如第一个fd115 列)与XML 文档的关系。
  • 我已经编辑了我刚刚添加的 xml 和 fd115 列..我认为它没有用,所以我将删除此列以及其他不需要的标题列...xml 不是那个large 它的大小只有 1.5MB,所以我认为我们不需要在这里使用 CLOB

标签: java xml oracle insert unmarshalling


【解决方案1】:

使用XMLTABLE。比如:

INSERT INTO import_xml (
  EXCHNAM,
  ENVTEXT,
  RPTCOD,
  RPTNAM,
  RPTFLEXKEY,
  MEMBID,
  MEMBLGLNAM,
  RPTPRNTEFFDAT,
  RPTPRNTRUNDAT,
  PARTICIPANT
)
SELECT EXCHNAM,
       ENVTEXT,
       RPTCOD,
       RPTNAM,
       RPTFLEXKEY,
       MEMBID,
       MEMBLGLNAM,
       RPTPRNTEFFDAT + ( TO_TIMESTAMP( RPTPRNTEFFTIM, 'HH24:MI:SS.FF2' )
                       - TO_TIMESTAMP( '00:00:00.00', 'HH24:MI:SS.FF2' ) ),
       RPTPRNTRUNDAT,
       PARTICIPANT
FROM   XMLTABLE(
         XMLNAMESPACES( DEFAULT 'http://www.eu.com/technology' ),
         '//fd115'
         PASSING XMLType( your_xml )
         COLUMNS
           EXCHNAM        VARCHAR2(50)  PATH './rptHdr/exchNam',
           ENVTEXT        VARCHAR2(20)  PATH './rptHdr/envText',
           RPTCOD         VARCHAR2(20)  PATH './rptHdr/rptCod',
           RPTNAM         VARCHAR2(180) PATH './rptHdr/rptNam',
           RPTFLEXKEY     VARCHAR2(180) PATH './rptHdr/rptFlexKey',
           MEMBID         VARCHAR2(50)  PATH './rptHdr/membId',
           MEMBLGLNAM     VARCHAR2(80)  PATH './rptHdr/membLglNam',
           RPTPRNTEFFDAT  TIMESTAMP     PATH './rptHdr/rptPrntEffDat',
           RPTPRNTEFFTIM  VARCHAR2(50)  PATH './rptHdr/rptPrntEffTim',
           RPTPRNTRUNDAT  DATE          PATH './rptHdr/rptPrntRunDat',
           PARTICIPANT    VARCHAR2(50)  PATH './fd115Grp/fd115KeyGrp/participantGrp/participant'
       );

db<>fiddle

(您需要检查 XQuery 路径并添加所有额外的列,但这应该为您提供可以使用的语法示例。)

此外,RPTPRNTEFFDAT 可以具有 TIMESTAMP 数据类型并存储 RPTPRNTEFFDATRPTPRNTEFFTIM xml 数据。 (您可以使用DATE 列,但RPTPRNTEFFTIM 数据似乎有小数秒,您会失去该精度。)

CREATE TABLE
    IMPORT_XML
    (
        fd115 VARCHAR2(180),
        RPTHDR VARCHAR2(180),
        EXCHNAM VARCHAR2(50),
        ENVTEXT VARCHAR2(20),
        RPTCOD VARCHAR2(20),
        RPTNAM VARCHAR2(180),
        RPTFLEXKEY VARCHAR2(180),
        MEMBID VARCHAR2(50),
        MEMBLGLNAM VARCHAR2(80),
        RPTPRNTEFFDAT TIMESTAMP, -- TIMESTAMP and remove the RPTPRNTEFFTIM column
        RPTPRNTRUNDAT DATE,
        fd115GRP VARCHAR2(180),
        fd115KEYGRP VARCHAR2(180),
        PARTICIPANTGRP VARCHAR2(180),
        PARTICIPANT VARCHAR2(50),
   ...

【讨论】:

  • 如何检查 XQuery 路径?我将如何在 Java 中使用这个查询?
  • 基本路径是//fd115,它应该对应于你的根元素;那么每一列都有一个路径,该路径应该反映 XML 结构中数据的路径。我不确定自己是否正确,因为我是手动输入的;您需要检查它们是否正确。至于在java中使用它......它是一个SQL语句,所以你创建一个准备好的语句,可以在中间使用PASSING XMLType( ? )并将你的XML文件作为CLOB绑定参数传递给准备好的语句,然后在数据库上执行它就像处理任何其他准备好的语句一样。
  • 只是想知道我可以直接在oracle数据库中运行这个sql查询以及如何运行它吗?这样我就可以确认我收到了什么数据,并过滤掉不需要的列 ...PASSING XMLType(your_xml_value_passed_as_a_clob_bind_variable) 我需要在这里传递什么?
  • @Andrew dbfiddle 中的代码至少适用于 Oracle 11gR2 及更高版本。如果您使用的是早期版本,请检查是否支持 XMLTABLEXMLTYPE,如果不支持,则需要更新您的问题并指定您使用的版本,并研究从其中提取数据的不同方法XML(尝试EXTRACTEXTRACTVALUE 函数)。
  • 将版本更改为 18c db<>fiddle 并且可以正常工作。由于它的 PL/SQL,您是在 SQL Developer 中将其作为脚本(F5 键盘快捷键)而不是作为语句(ctrl-Enter 键盘快捷键)运行吗?除了这个建议之外,我不确定我是否可以帮助让其他工作代码在您的本地机器上运行。
猜你喜欢
  • 2010-12-02
  • 2016-11-27
  • 2013-10-06
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2012-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多