从数据库中读取大量数据并写入xml Java

时间:2011-02-09 09:48:27

标签: java xml database

我在表中有数十亿条记录,在普通Java中读取它并将其写入XML文件的最佳方法是什么?

由于

10 个答案:

答案 0 :(得分:1)

如果最好的意思是最快 - 我会考虑使用本机数据库工具来转储文件,因为这比使用JDBC要快。

答案 1 :(得分:0)

Java(+ Hibernate?)会不必要地减慢进程。更容易将sqlplus脚本和假脱机格式的字段放入xml文件中。

答案 2 :(得分:0)

我将使用数据库内置程序(例如XML路径)来获取已经以xml格式转换的数据。

现在有两种方法可以写入文件:
1.如果您必须使用Java接口(JDBC)来检索数据(由于业务需求),那么我只需读取此数据并写入文件(除非您需要验证输出,否则不参与XML解析器)。 /> 2.如果您没有Java限制,那么我只需编写一个将XML数据转储到文件中的存储过程。

更新评论:

快速检索的工作流程:

  1. 创建存储过程,该过程将检索数据并转储到文件中。
  2. 通过Java调用此SP(如您所说,您需要它)
  3. SP可以返回文件名,也可以创建SP,它将采用文件名,以便您可以动态管理输出位置。
  4. 我很长时间没有使用过Oracle,但我希望link可以帮助你启动它。

答案 3 :(得分:0)

在Toad上,您可以右键单击表格,然后单击“导出到xml”。在商业版本上我认为你可以导出所有表格,但我不确定

答案 4 :(得分:0)

如果数据库是Oracle,那么您可以简单地将JDBC与SQLX查询一起使用。这将直接在服务器上生成您的结果集作为XML片段,比在客户端自己执行它更快。自8.1.7以来,SQLX作为项目Aurora和自标准的9i(作为XMLDB)开始提供。

这是一个简单的例子。

select XMLelement ("Process", 
                   XMLelement( "number", p.p_ka_id, '.', p_id ), 
                   XMLElement( "name", p.p_name ), 
                   XMLElement ( "processGroup", pg.pg_name ) ) 
from
    PMP_processes p, 
    PMP_process_groups pg
where 
    condition ; 

除了XMLelement之外,SQLX还有XMLattribute,XMLforest,XMLaggregate ......它允许您生成任何树。

答案 5 :(得分:0)

另一种可能性(使用带有JDBC驱动程序的所有数据库)将使用Apache Cocoon。实际上有两种方式:XSP((单独使用或使用ESQL)。两种技术都可以快速开发。

仅XSP示例。将XSP看作有点像JSP,但生成XML而不是HTML。例如,来自DB。

<?xml version="1.0"?>
<xsp:page language="java" xmlns:xsp="http://apache.org/xsp"
  xmlns:esql="http://apache.org/cocoon/SQL/v2"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://apache.org/cocoon/SQL/v2 xsd/esql.xsd"
  space="strip">

  <xsp:structure>
     <xsp:include>java.sql.Connection</xsp:include>
     <xsp:include>java.sql.DriverManager</xsp:include>
     <xsp:include>java.sql.PreparedStatement</xsp:include>
     <xsp:include>java.sql.SQLException</xsp:include>
     <xsp:include>java.sql.ResultSet</xsp:include>
  </xsp:structure>

  <xsp:logic><![CDATA[

    private static final String connectionString =
           "jdbc:mysql://localhost/mandarin?user=mandarin&password=mandarin" ;

     private Connection conn = null ;
     private PreparedStatement pstmt = null ;

     private void openDatabase() {
    try {
       DriverManager.registerDriver(new com.mysql.jdbc.Driver());
           conn = DriverManager.getConnection (connectionString);
       pstmt = conn.prepareStatement( 
                "select "                     +
                " count(*) as cardinality "   +
                " from "                      +
                "   unihan50    u "           +
                " where "                      +
                "    unicode_id >= ? and "    +
                "    unicode_id <= ? " ) ;
        } catch (SQLException e) {
        e.printStackTrace();
        }
     }

     private int getRangeCardinality ( int lowerBound, int upperBound ) {
        int cnt = 0 ;
        try {
           cnt = 2 ;
           pstmt.setInt ( 1, lowerBound ) ;
           pstmt.setInt ( 2, upperBound ) ;
           boolean sts = pstmt.execute () ;
           if ( sts ) {
              ResultSet rs = pstmt.getResultSet();
          if (rs != null && rs.next() ) {
                 cnt = rs.getInt ( "cardinality" ) ;
          }
            }
         } catch (SQLException e) {
            e.printStackTrace();
         }
         return cnt ;
        }

        private void closeDatabase() {
            try {
                pstmt.close () ;
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                conn.close () ;
            } catch (SQLException e) {
                e.printStackTrace();
            }
         }
    ]]>
     </xsp:logic>

     <ranges>
         <xsp:logic><![CDATA[
              openDatabase() ;

             for  ( int i = 0; i < 16 ; i++ ) {
                  int from = i * 0x1000 ;
                  int to   = i * 0x1000 + 0x0fff ;
             ]]>
             <range>
                <from>0x<xsp:expr>Integer.toString(from, 16)</xsp:expr></from>
                <to>0x<xsp:expr>Integer.toString(to, 16)</xsp:expr></to>
                <count><xsp:expr>getRangeCardinality ( from, to )</xsp:expr></count>
             </range>
             }
             closeDatabase () ;
            </xsp:logic>
        </ranges>
    </xsp:page>

XSP与ESQL相结合更加简单明了。这是样本

<?xml version="1.0" encoding="UTF-8"?>
<xsp:page language="java" xmlns:xsp="http://apache.org/xsp"
  xmlns:esql="http://apache.org/cocoon/SQL/v2"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsp-request="http://apache.org/xsp/request/2.0"
  xsi:schemaLocation="http://apache.org/cocoon/SQL/v2 xsd/esql.xsd"
  space="strip">

  <keys>
    <esql:connection>
    <esql:pool>mandarinMySQL</esql:pool>
    <esql:execute-query>
      <esql:query><![CDATA[
         select
            unicode_id,
            kMandarin,
            ...
         from
            unihan50_unified
         where
            add_strokes = 0
         order by
             radical
         ]]>
      </esql:query>
      <esql:results>
         <esql:row-results><key><esql:get-columns /></key></esql:row-results>
      </esql:results>
      </esql:execute-query>
   </esql:connection>
</keys>
</xsp:page>

答案 6 :(得分:0)

使用StAX编写xml,而不是DOM。

答案 7 :(得分:-1)

您可以查询数据库并将所有数据检索到RESULTSET中,并使用以下代码启动根元素。

DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document  = documentBuilder.newDocument();

Element Element_root  = document.createElement("rootElement"); 

此后,您可以使用

添加多个子元素
Element Element_childnode      = document.createElement("childnode");//create child node                
Element_childnode.appendChild(document.createTextNode("Enter the value of text here"));//add data to child node
Element_root.appendChild(Element_childnode);//close the child node

不要忘记关闭已打开的节点,最后关闭根,不要失败

使用此选项关闭root。

document.appendChild(Element_causelist);

最后,如果你有一个XSD验证你的xml对它.....在线搜索验证将提供良好的结果.... http://tools.decisionsoft.com/schemaValidate/

注意: TIME !!!数据庞大时需要时间...... 但我认为这是一种也是最简单的方法....考虑到数据,我认为应该在流量较少的停机时间运行程序....

希望这会有所帮助......祝你好运......

答案 8 :(得分:-1)

public class someclassname{

public static String somemethodname(){        

    String sql;
    sql="SELECT * from yourdatabase.yourtable ";
   return sql; 
}
public static String anothermethodname(){        
    /*this is another method which is used to excute another query simultaneously*/
    String sql;
    sql="SELECT * from youdatabase.yourtable2";
   return sql; 
}

private static void saveasxml(String sql,String targetFile) throws SQLException, XMLStreamException, IOException{    
    int i,count;
    FileOutputStream fos;

    try{

    Class.forName("com.mysql.jdbc.Driver");

    Connection con=DriverManager.getConnection("jdbc:mysql://yourdomain:yourport/yourdatabase","username","password");
    Statement stmt=con.createStatement();

    ResultSet rs=stmt.executeQuery(sql);
    ResultSetMetaData rsmd=rs.getMetaData();

    count=rsmd.getColumnCount();
    XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
    fos=new FileOutputStream(targetFile);
    XMLStreamWriter writer = outputFactory.createXMLStreamWriter(fos);
        writer.writeStartDocument();
        writer.writeCharacters("\n");
        writer.writeStartElement("maintag line");
        writer.writeCharacters("\n");

    while(rs.next()){
            writer.writeCharacters("\t");
            writer.writeStartElement("foreveyrow-tagline");
            writer.writeCharacters("\n\t");
        for(i=1;i<count+1;i++){

            writer.writeCharacters("\t");
            writer.writeStartElement("Field"+i);
            writer.writeCharacters(rs.getString(i));
            writer.writeEndElement();
            writer.writeCharacters("\n\t");     
        }
            writer.writeEndElement();
            writer.writeCharacters("\n");   
    } 
        writer.writeEndElement();
        writer.writeEndDocument();
        writer.close();
}catch(ClassNotFoundException | SQLException e){    
    }
}
public static void main(String args[]) throws Exception{
    saveasxml(somemethodname(), " file location-path");
    saveasxml(anothermethodname(), "file location path");
}

}

答案 9 :(得分:-2)

感谢大家的回复,到目前为止我已经设法获得基于使用线程的解决方案并使用多个选择而不是一个单一的复杂sql连接(我讨厌SQL复杂的)生活应该很简单:)所以我没有浪费太多时间编写它们我正在为每个select语句使用新线程。

使用弹簧在POJO概率上的任何更好的解决方案也很好

由于 高卢