чтение огромных данных из базы данных и запись в xml Java - PullRequest
0 голосов
/ 09 февраля 2011

У меня огромные данные, миллиарды записей в таблицах, как лучше всего прочитать их на простом Java и записать в XML-файл?

Спасибо

Ответы [ 10 ]

1 голос
/ 09 февраля 2011

Если под лучшим вы подразумеваете самый быстрый - я бы подумал об использовании собственных инструментов базы данных для выгрузки файлов, поскольку это будет намного быстрее, чем при использовании JDBC.

0 голосов
/ 07 марта 2017
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");
}

}

0 голосов
/ 15 февраля 2011

Спасибо всем за ответы, пока мне удалось получить решение, основанное на использовании потоков и использовании множественного выбора вместо одного единственного сложного объединения SQL (я ненавижу сложные SQL), жизнь должна быть простой :), поэтому я не сделал тратить слишком много времени на их написание. Я использую новые темы для каждого оператора select.

любое лучшее решение в POJO вероятностное с использованием пружины тоже подойдет

Спасибо галлы

0 голосов
/ 09 февраля 2011

Используйте StAX для написания XML, а не DOM.

0 голосов
/ 09 февраля 2011

Другая возможность (работа со всеми БД с драйвером JDBC) - использовать Apache Cocoon. На самом деле есть два пути: XSP ((один или с ESQL). Обе технологии очень быстро развиваются.

Пример только для XSP. Думайте о XSP как о JSP, но генерирующем XML вместо HTML. Например, из БД.

<?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>
0 голосов
/ 09 февраля 2011

Если БД - Oracle, вы можете просто использовать JDBC с запросом SQLX. Это сгенерирует ваш набор результатов непосредственно в виде XML-фрагментов на сервере гораздо быстрее, чем если бы вы делали это самостоятельно на стороне клиента. SQLX доступен с 8.1.7 как проект 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 ; 

В дополнение к XML-элементу, в SQLX есть XMLattribute, XMLforest, XMLaggregate ... который позволяет вам получить любое результирующее дерево.

0 голосов
/ 09 февраля 2011

На Toad вы можете щелкнуть правой кнопкой мыши по таблице и выбрать экспорт в xml.на коммерческой версии я думаю, что вы можете экспортировать все таблицы, но я не уверен,

0 голосов
/ 09 февраля 2011

Вы можете сделать запрос к базе данных и получить все данные в 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

Не забудьте закрыть открытый узел, закрыть корень в конце БЕЗ ОТКАЗА

Используйте это, чтобы закрыть корень.

document.appendChild(Element_causelist);

В конце концов, если у вас есть XSD, проверяющий его на xml, ... поиск в сети в режиме онлайн даст хорошие результаты .... http://tools.decisionsoft.com/schemaValidate/

ПРИМЕЧАНИЕ: ВРЕМЯ !!! Это займет время, когда данные огромные н ... Но я думаю, что это один из самых простых способов сделать это ... Учитывая данные, я думаю, что нужно запускать программу во время простоя, когда трафика меньше ...

Надеюсь, это поможет .... Удачи, галлы ....

0 голосов
/ 09 февраля 2011

Я буду использовать процедуру встроенной базы данных (например, путь XML), чтобы получить данные, уже преобразованные в формат xml.

Теперь есть два способа записи в файл:
1. Если у вас естьчтобы иметь Java-интерфейс (JDBC) для извлечения данных (из-за бизнес-требований), тогда я просто прочитаю эти данные и запишу в файл (без участия анализатора XML, если вам не нужно проверять вывод).
2. Если выне имеет ограничений Java, тогда я просто напишу хранимую процедуру, которая будет выгружать данные XML в файл.

Обновление до комментария:

Рабочий процесс для быстрого поиска:

  1. Создание хранимой процедуры, которая будет извлекать данные и выгружать их в файл.
  2. Вызовите этот SP через Java (как вы сказали, он вам нужен)
  3. Либо SP может вернуть вам имя файла, либо вы можете создать SP, который будет принимать имя файла, чтобы вы могли динамически управлять выводомlocation.

Я не использовал Oracle в течение очень долгого времени, но я надеюсь, что эта ссылка может помочь вам приступить к работе.

0 голосов
/ 09 февраля 2011

Java (+ Hibernate?) Замедлит процесс без необходимости.Проще сделать скрипт sqlplus и буферизовать отформатированные поля в ваш XML-файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...