2009-08-27 88 views
2

我需要從DB2表中提取數據,對每個返回的行運行一些處理並輸出到平面文件。我正在使用iBatis,但發現使用queryForList我開始出現內存不足錯誤,我將看看增加的100k +行數據。Java - 使用iBatis從數據庫檢索大量數據

我看了使用queryWithRowHandler代替,但iBatis的RowHandler所以如果它得到一個錯誤我不能正確接口不扔從handleRow功能異常報告並停止迭代其餘數據。看起來我可以拋出一個RuntimeException,但這並不會讓我成爲一個乾淨利落的工作方式。

我希望能夠停止處理,同時拋出一個有意義的異常,指出數據操作,文件訪問等是否發生錯誤。

有沒有人有過使用這種方法的經驗,或者有使用iBatis的替代解決方案。我知道我可以在不使用iBatis的情況下執行此操作,只是使用JDBC,但由於iBatis用於應用程序中的所有其他數據庫訪問,如果可能,我希望利用此架構。

回答

3

1)簽名與籤例外創建自己的RowHandler接口:

public interface MySpecialRowHandler { 
    public void handleRow(Object row) 
     throws DataException, FileException, WhateverException; 
} 

2)SqlMapDaoTemplate繼承(甚至更好,delegate)以添加將使用相同的管理自己的處理程序的新方法在簽名例外:

public class MySpecialTemplate extends SqlMapDaoTemplate { 
    ... 
    public void queryWithRowHandler(String id, 
     final MySpecialRowHandler myRowHandler 
    ) throws DataException, FileException, WhateverException { 
     // "holder" will hold the exception thrown by your special rowHandler 
     // both "holder" and "myRowHandler" need to be declared as "final" 
     final Set<Exception> holder = new HashSet<Exception>(); 
     this.queryWithRowHandler(id,new RowHandler() { 
      public void handleRow(Object row) { 
       try { 
        // your own row handler is executed in IBatis row handler 
        myRowHandler.handleRow(row); 
       } catch (Exception e) { 
        holder.add(e); 
       } 
      } 
     }); 
     // if an exception was thrown, rethrow it. 
     if (!holder.isEmpty()) { 
      Exception e = holder.iterator().next(); 
      if (e instanceof DataException)  throw (DataException)e; 
      if (e instanceof FileException)  throw (FileException)e; 
      if (e instanceof WhateverException) throw (WhateverException)e; 
      // You'll need this, in case none of the above works 
      throw (RuntimeException)e; 
     } 
    } 
}      

3)你的業務代碼看起來就像這樣:

// create your rowHandler 
public class Db2RowHandler implements MySpecialRowHandler { 
    void handleRow(Object row) throws DataException, FileException, WhateverException { 
     // what you would have done in ibatis RowHandler, with your own exceptions 
    } 
} 
// use it. 
MySpecialTemplate template = new MySpecialTemplate(daoManager); 
try { 
    template.queryWithRowHandler("selectAllDb2", new Db2RowHandler()); 
} catch (DataException e) { 
    // ... 
} catch (FileException e) { 
    ...