1

我需要通過讀取xml來寫入文件,其中包含要從數據庫中提取的格式信息和值。我正在處理大量記錄(200,000)。 我已經嘗試保留內存中的所有數據,但出現內存不足錯誤。 我曾嘗試一次又一次地打擊數據庫,但後來我得到了性能問題。隨着查詢被再次擊中而降低性能。涉及用於過程以最小內存消耗寫入文件的設計模式

步驟:

  1. 擊中分貝來獲得所有的記錄進行文件是要創建使用JAXB
  2. 創建從步驟1中獲得的所有數據的地圖
  3. 讀取XML文件從步驟1得到的。
  4. 遍歷地圖
  5. 導出數據所需要的從格式對象顯示在步驟2
  6. 創建
  7. 附加結果每個記錄的字符串,然後寫相同 到文件

雖然,最後我通過讀數據的預定計數一次,寫文件這一點,然後旁邊一堆工作,解決了這個。但我沒有遵循任何設計模式。

是否有一種設計模式使用最少的內存,並讓我有效地寫文件?

回答

2

設計模式被稱爲Pagination(使用遊標)。例如,當您向Oracle DB發送查詢時,返回的結果集中的默認結果數爲50.只有當您要求結果集獲得next()時,它纔會返回下一個50個結果。這就是大多數的DB是如何工作的,並設計成高效地爲這樣的格局(見本code example):

public static void viewTable(Connection con, String dbName) 
    throws SQLException { 

    Statement stmt = null; 
    String query = 
     "select COF_NAME, SUP_ID, PRICE, " + 
     "SALES, TOTAL " + 
     "from " + dbName + ".COFFEES"; 

    try { 
     stmt = con.createStatement(); 
     ResultSet rs = stmt.executeQuery(query); 
     while (rs.next()) { 
      String coffeeName = rs.getString("COF_NAME"); 
      int supplierID = rs.getInt("SUP_ID"); 
      float price = rs.getFloat("PRICE"); 
      int sales = rs.getInt("SALES"); 
      int total = rs.getInt("TOTAL"); 
      System.out.println(coffeeName + "\t" + supplierID + 
           "\t" + price + "\t" + sales + 
           "\t" + total); 
     } 
    } catch (SQLException e) { 
     JDBCTutorialUtilities.printSQLException(e); 
    } finally { 
     if (stmt != null) { stmt.close(); } 
    } 
} 

所以,你可以打開該文件,並寫入每「頁」你得到的結果,問爲下一頁等等。一旦你完成 - 關閉文件。

+0

好吧。那麼修改這個場景的'Composite'或'Visitor'設計模式怎麼樣? – jfun 2015-01-20 19:40:51

+0

@ FarhangAmary我不明白你的意見。如果您認爲這些設計模式與問題相關 - 請將其作爲答案解釋如何。 – alfasin 2015-01-20 19:43:01

+0

感謝您的快速響應。我從來沒有在Java批處理中使用過分頁模式。你可以請分享一個分頁設計模式的鏈接,這樣我可以更多地瞭解這種模式。 – 2015-01-20 19:46:38

0

如果您正在寫入XML,我建議您在讀入時寫出每條記錄。這樣,您一次只需要足夠的內存用於一條記錄,並且無論您擁有多少條記錄都無關緊要。

例如

Statement stmt = null; 
String query = 
    "select COF_NAME, SUP_ID, PRICE, " + 
    "SALES, TOTAL " + 
    "from " + dbName + ".COFFEES"; 

try { 
    stmt = con.createStatement(); 
    ResultSet rs = stmt.executeQuery(query); 
    while (rs.next()) { 
     xmlFile.println("<coffee>\n" + 
       "<coffeename>" + rs.getString("COF_NAME") + "</coffeename>\n" + 
       "<supId>" + rs.getInt("SUP_ID")+ "</supId>\n" + 
       "<price>" + rs.getFloat("PRICE") + "</price>\n" + 
       "<sales>" + rs.getInt("SALES") + "</sales>\n" + 
       "<total>" + rs.getInt("TOTAL") + "</total>\n" + 
       "</coffee>"); 
    } 
} catch (SQLException e) { 
    JDBCTutorialUtilities.printSQLException(e); 
} finally { 
    if (stmt != null) { stmt.close(); } 
} 

如果包含特殊字符,則可能需要將字符串轉義出來。

+0

我不需要將文件寫入XML。我需要在充當模板的XML文件的幫助下編寫文本文件。 XML文件包含有關要顯示的字段名稱和字段值的信息。 – 2015-01-20 20:16:36

+0

@AkhilKhandelwal好了,但您可以使用一次處理一條記錄並將數據流傳送到任何位置的策略。 – 2015-01-20 20:22:27

+0

感謝彼得,我也是這樣做,但想要一個設計模式,以確保策略是正確的,如果沒有改變。 – 2015-01-20 20:32:00