2

我需要从 DB2 表中提取数据,对每个返回的行运行一些处理并输出到平面文件。我正在使用 iBatis,但发现使用queryForList我开始出现内存不足错误,我将看到 100k+ 行数据增加。

我已经研究过使用queryWithRowHandler了,但是 iBatis RowHandler接口不会从它的handleRow函数中抛出异常,所以如果它收到错误,我不能正确地报告它并停止迭代其余数据。看起来我可以抛出一个 RuntimeException ,但这并没有让我觉得这是一种简洁的做事方式。

我希望能够在抛出一个有意义的异常时停止处理,指示错误是否发生在数据操作、文件访问或其他方面。

有没有人有过这种方法的经验或有使用 iBatis 的替代解决方案。我知道我可以在不使用 iBatis 的情况下仅使用 JDBC 来执行此操作,但由于 iBatis 用于我的应用程序中的所有其他数据库访问,因此我希望尽可能利用此架构。

4

1 回答 1

3

1)创建您自己的 RowHandler 接口,并在签名中检查异常:

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

2)从 SqlMapDaoTemplate 继承(甚至更好,委托)以添加一个新方法,该方法将管理您自己的处理程序,并在签名中使用相同的异常:

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) {
    ...
于 2009-08-28T14:39:23.967 回答