2012-06-22 52 views
1

我的問題與如何做某事無關,它更多的是如何幫助提高性能。我爲這篇較長的文章道歉,但我認爲這是關於表演,我應該發佈所有關於我在做什麼的細節,看看有沒有人可以幫忙。使用BLOB獲得更好的性能,在JAVA上

我必須做一個程序,從2個不同的數據庫獲取信息,創建一個元數據,其相應的BLOB(pdf文件)並將其壓縮。
只有在數據庫中找到BLOB對象時纔會創建元數據文件。我設法這樣做了,但問題有時我可能會在查詢中得到高達80k的結果,並且可能需要長達20小時才能這樣做,考慮到每個blob對象不超過100 KB,這是荒謬的。

我有一個交易數據庫(讓我們稱之爲TEQ8P),其中存儲了元數據的所有ID和信息。我查詢的日期和狀態的數據(這很爛,但我沒有任何其他的過濾器,這是要求)

TEQ8P.openConnection(); 
Boolean flag = TEQ8P.ExecuteQuery("select tr.legaltransnumber, cc.country_code, tr.transnumber, tr.postingdate, tr.transdate from EQUATE.transheader tr inner join companycode_country cc on tr.tocompanycode = cc.company_code where tr.transtype = 'IC' and tr.transdate between to_date(" + date + ", 'DD/MM/YYYY') and to_date(" + nextday + ", 'DD/MM /YYYY')"); 

public Boolean ExecuteQuery(String query) { 
     Statement stmt; 
     ResultSet rs = null; 
     try { 
      stmt = connection.createStatement(); 
      rs = stmt.executeQuery(query); 
      if(!rs.isBeforeFirst()) 
       return false; 
      rowset = new CachedRowSetImpl(); 
      rowset.populate(rs); 
      metadata = rs.getMetaData();    
      rs.close(); 
      stmt.close(); 
      return true; 
     } catch (SQLException e) { 
      HLog.error(e.getMessage()); 
      e.printStackTrace(); 
      return false; 
      //System.out.println(query);    
     } 
     finally 
     { 
      closeConnection(); 
     } 
} 

我(再次按要求)使用JAVA 1.5,所以我下載了cachedrowsetimp從罐子oracle,所以一旦我完成查詢數據,我將它保存到內存並關閉連接。

之後,我開始瀏覽cachedrowset並查詢倉庫數據庫中的每個ID。我不能做一個選擇「在哪裏」,因爲沒有辦法知道是否會找到所有的id,並且「in」只會返回找到的項目,我不知道它沒有的項目找。但是,如果您有任何建議,請!

因此,我使用preparedStatement在ORACLE上使用綁定變量並開始編寫blob對象。

我的第一個問題,有沒有更好的方式來編寫blob文件?更快的方式?

if(flag)  
    { 
     String Query = "select wh.transnumber, wh.image from EQUATEWH.legalimage wh where wh.transnumber = ?"; 
     WEQ8I.openConnection(); 
     WEQ8I.setPreparedStmt(Query); 
     WEQ8I.WriteBlobs(PDF, TEQ8P.getRowsSet(), IC_FILE);  
     WEQ8I.closePrepStmt(); 
     WEQ8I.closeConnection(); 
     FileUtils.createZip(prop.getProperty("ZIPDIR_IC"), lsize, prop.getProperty("ZIPNAME_IC")); 

public void WriteBlobs(String path, CachedRowSetImpl set, IMP_File IC_FILE) 
{ 
    ResultSet rs = null; 
    try 
    { 
     while(set.next()) 
      {     
       pstmt.setString(1, set.getString(3)); 
       rs = pstmt.executeQuery(); 
       if(!rs.isBeforeFirst()) 
       { 
        System.out.println("invoice " + set.getString(3) + "was not found on W database"); 
        ErrorFile.writeErrorFile(set.getString(3)); 
       } 
       else 
       { 
        //getting the name of the PDF file, if no ID use legaltransnumber 
        String ID = set.getString(1); 
        if(ID == null) 
        { 
         ID = set.getString(3); 
        } 
        while(rs.next()) 
        { 
         FileOutputStream fos = null; 
         try 
         { 
          Blob blob = rs.getBlob(2); 
          InputStream is = blob.getBinaryStream(); 
          fos = new FileOutputStream(path + ID + ".pdf"); 
          int i = 0; 
          while ((i = is.read()) != -1) 
          { 
           fos.write(i); 
          } 
          fos.close(); 
          is.close(); 
          IC_FILE.fillIMPFile("IC", ID, set.getString(3), set.getString(2), set.getString(5)); 
         }catch (Exception e) 
         { 
          e.printStackTrace(); 
          ErrorFile.writeErrorFile(set.getString(3)); 
         } 
        }       
       } 
       rs.close();     
      } 
     IC_FILE.writeFile(); 

    } catch (SQLException e) 
    { 
     System.out.println("Problem when trying to create Record: " + path); 
     HLog.error(e.getMessage()); 
     e.printStackTrace(); 
     try 
     { 
      ErrorFile.writeErrorFile(set.getString(3)); 
     }catch (Exception ex) 
     { 
      ex.printStackTrace(); 
      HLog.error(e.getMessage()); 
     } 
    } 

} 

如果查詢發現在WarehouseDB該ID的結果和圖像不爲空(這意味着它不會去零除外),我創建了metadafile這是IC_FILE。 IC_FILE不會寫入文件,它會將所有內容保存到內存中,當它寫完文件時,我認爲這可以幫助提高性能,因爲它不需要對每個文件執行I/O操作,只需要一次IC_FILE.writefile()。

要創建元數據文件,我還必須(根據要求再次)從文件中獲取容器名稱。要檢索容器名稱,我必須使用Transactional數據庫中的3個字段,將它們連接起來並在該文件中搜索它們。 這是我如何創建IMP文件,首先從每個記錄獲得的數據:

public void fillIMPFile(String type, String ID, String ID2, String companyCode, String date) 
{ 
    date = date.substring(0, 10); 
    date = date.replace("-", "/"); 
    date = date.substring(5, 7) + "/" + date.substring(8, 10) + "/" + date.substring(0, 4); 
    String Name = prop.getProperty("NAME"); 
    String info = prop.getProperty(type); 
    String DOS = Name + info + ID + "."; 
    String NOTES = Name + " " + info + " "; 
    info += getContainer(companyCode, date, type); 


    if(type.equals("IC")) 
    { 
     String desc = prop.getProperty("DESC_PDF"); 
     DOS += "pdf"; 
     NOTES += desc + " " + ID + " " + ID2; 

     buffer += info + "\t" + date + "\t" + date + "\t" + DOS + "\t" + NOTES + "\t" 
       + NOTES + "\t" + ID2; 
    } 

得到我使用對象的屬性的容器,但我想有可能是更好的選擇?哈希圖可能?

public String getContainer(String companyCode, String Date, String type) 
{ 
    Calendar cal = Calendar.getInstance(); 
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy"); 
    Date = sdf.format(cal.getTime()); 
    //mal siempre pondra 2012 
    String data = type + companyCode + Date; 
    String container = containers.getProperty(data); 

    if(container == null) 
    { 
     data = type + "WW" + Date; 
     container = containers.getProperty(data); 
    } 
    return container; 
} 

finaly寫入文件:

public void writeFile() 
{ 
    try 
    { 
     FileWriter fw = new FileWriter(File, true); 
     BufferedWriter bw = new BufferedWriter(fw); 
     bw.write(buffer); 
     bw.close(); 
    }catch (IOException e) 
    { 
     e.printStackTrace(); 
     HLog.error(e.getMessage()); 
    } 
} 

謝謝! 丹尼爾

+0

忘了提,容器文件中有2700個容器名稱創建超過1個容器文件,所以它搜索一個一個:S –

回答

0

固定...使用綁定變量,每年

相關問題