2009-08-27 55 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) { 
    ...