Mysql 如何使用此coldfusion代码读取大型XML文件并将数据插入数据库?

Mysql 如何使用此coldfusion代码读取大型XML文件并将数据插入数据库?,mysql,xml,database,coldfusion,import,Mysql,Xml,Database,Coldfusion,Import,我使用ColdFusion(openBlueDragon)将一个大(200MB)xml文件中的数据插入数据库,而不必将整个文件加载到内存中,这是我传统的做法。我确实在这里发现了一个非常类似的问题:这似乎是我正在寻找的答案 然而,我对java的熟练程度还不足以理解代码并使其适应我的需要。我没有办法回复发布代码的专家(@orangepips),否则我就不会发布类似的问题 我的xml文件如下所示: <allItems> <item> <subje

我使用ColdFusion(openBlueDragon)将一个大(200MB)xml文件中的数据插入数据库,而不必将整个文件加载到内存中,这是我传统的做法。我确实在这里发现了一个非常类似的问题:这似乎是我正在寻找的答案

然而,我对java的熟练程度还不足以理解代码并使其适应我的需要。我没有办法回复发布代码的专家(@orangepips),否则我就不会发布类似的问题

我的xml文件如下所示:

 <allItems>
    <item>
        <subject>The subject text</subject>
        <date>2007-05-21 04:03:00</date>
        <content>text content often contains many paragraphs of text</content>
        <author>JPass78</author> 
    </item>
</allItems>

主题文本
2007-05-21 04:03:00
文本内容通常包含许多文本段落
JPass78
这就是我试图为我的目的而修改的代码。我对其进行了一些修改,以包括我自己的字段名:

<cfset fis = createObject("java", "java.io.FileInputStream").init(
"#getDirectoryFromPath(getCurrentTemplatePath())#/file.xml")>
<cfset bis = createObject("java", "java.io.BufferedInputStream").init(fis)>
<cfset XMLInputFactory = createObject("java", "javax.xml.stream.XMLInputFactory").newInstance()>
<cfset reader = XMLInputFactory.createXMLStreamReader(bis)>

<cfloop condition="#reader.hasNext()#">
<cfset event = reader.next()>
<cfif event EQ reader.START_ELEMENT>
    <cfswitch expression="#reader.getLocalName()#">
        <cfcase value="allItems">
            <!--- root node, do nothing --->
        </cfcase>
        <cfcase value="item">
            <!--- set values used later on for inserts, selects, updates --->
        </cfcase>
        <cfcase value="subject">
            <!--- some selects and insert --->
        </cfcase>
        <cfcase value="contentdate">
            <!--- insert or update --->
        </cfcase>
        <cfcase value="content">
        </cfcase>
        <cfcase value="author">
         </cfcase>  
    </cfswitch>
</cfif>
</cfloop>
<cfset reader.close()>

我只有一个表,我试图弄清楚如何访问每个XML元素的值,以便一次插入一行?如下所示:插入内容(主题、内容日期、内容、作者)
值(“主题文本”,2007-5-21 04:03:00,“此处文本内容”,“JPass78”)

一种可能性是每次遇到
元素时初始化数据
结构。当子元素经过(
,…)时,提取它们的文本并将其添加到您的结构中。然后,当您到达
元素时,执行验证/插入。也许有更好的办法。但这应该会给你一些可以合作的东西

更新:我预感数据库批量加载工具会是一个更好的选择。原来是;)有关详细信息,请参见JPass的答案

<cfset fis = createObject("java", "java.io.FileInputStream").init(pathToYourFile)>
<cfset bis = createObject("java", "java.io.BufferedInputStream").init(fis)>
<cfset XMLInputFactory = createObject("java", "javax.xml.stream.XMLInputFactory").newInstance()>
<cfset reader = XMLInputFactory.createXMLStreamReader(bis)>

<cfloop condition="#reader.hasNext()#">
    <cfset event = reader.next()>
    <cfif event EQ reader.START_ELEMENT>
        <cfswitch expression="#reader.getLocalName()#">
            <cfcase value="item">
                <!--- start a new data row --->
                <cfset row = {}>
            </cfcase>
            <cfcase value="subject">
                <!--- extract the subject text --->
                <cfset row.subject = reader.getElementText()>
            </cfcase>
            <cfcase value="date">
                <!--- extract the date text --->
                <cfset row.date = reader.getElementText()>
            </cfcase>
            <cfcase value="content">
                <!--- extract the content text --->
                <cfset row.content = reader.getElementText()>
            </cfcase>
            <cfcase value="author">
                <!--- extract the author text --->
                <cfset row.author = reader.getElementText()>
            </cfcase>  
        </cfswitch>
    <cfelseif event EQ reader.END_ELEMENT>
        <!--- we have reached the end of the row. time to insert the data --->
        <cfif reader.getLocalName() eq "item">
            <cfdump var="#row#" label="Debug Row Data">    
            <!--- ... validate / insert "row" data into database --->
        </cfif>
    </cfif>
</cfloop>

<cfset fis.close()>
<cfset reader.close()>

不要使用COLDFUSION将大型XML文件导入MYSQL数据库,而是使用MYSQL命令“加载XML内嵌”

以下是简单、轻松、快速的代码:

将XML内嵌“pathtofile/file.XML”加载到由“”标识的表名称行中

我的xml文件使用与数据库表完全相同的字段名。由标识的行告诉命令,我的xml文件中的字段名将对应于我的表中的数据库字段,它们将在标记之间找到

仅供参考,这是我自己的命名格式。您的文件可能会有另一个与您正在处理的数据相关的标记名。例如,如果您的xml文件用于员工数据,则可以使用

可在MYSQL5.5中找到-有关加载XML内嵌的参考,请访问:

谢谢,Leigh,这很有效。它并没有我希望的那么快,但我正在本地计算机上测试,我打赌这会让它慢一点。大约需要5分钟。对于每个项目有24个字段和1000个项目的xml文件。我想我可能会尝试创建一个查询,看看这是否会加快速度。我的XML文件可能有10到1000条记录。谢谢好吧,循环是很耗时的,不管你用什么方法来切割它。此外,数据库对一次可以处理多少sql也有限制。因此,您可能无法在一(1)个查询中完成所有操作。但是,将其分块,以减少数据库的点击次数,应该会有所帮助。您的数据库是否支持批量加载
xml
?SQL女士是这样做的。它的批量加载工具是一个
COM
对象。但速度相当快。我还想知道是否最好将数据转换成更小的平面文件。因为大多数数据库都有批量导入文本文件的工具。这可能是一个疯狂的想法……是的!我使用CFML的理由是,在插入之前,我可以使用逻辑来确定导出文件中存在哪些字段。虽然字段名总是相同的,但我不知道xml文件中将包含哪些字段。MYSQL“loadXMLinfle”语句可以在0.62秒内完成我需要的1000行操作。如果其他人需要类似的解决方案:通过MYSQL命令行:将XML infle“pathtofile/file.XML”加载到由“”标识的表_name行中;标记之间的字段名与数据库字段名匹配,并且导出文件中的字段不重要。太好了!我想数据库导入工具会快得多。但这比我想象的还要好;)你应该把它写下来作为回答并接受它。