Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在JDBC/iBATIS3中迭代大型结果集的最佳方法是什么?_Java_Jdbc_Ibatis - Fatal编程技术网

Java 在JDBC/iBATIS3中迭代大型结果集的最佳方法是什么?

Java 在JDBC/iBATIS3中迭代大型结果集的最佳方法是什么?,java,jdbc,ibatis,Java,Jdbc,Ibatis,我们试图迭代数据库中的大量行,并将它们转换为对象。行为如下: 结果将按序列id排序,当序列id更改时,将创建一个新对象。创建的对象将被发送到一个外部服务,有时在发送另一个服务之前必须等待,这意味着不会立即使用下一组数据 我们已经在iBATIS3中投入了代码,因此iBatis解决方案将是我们的最佳方法。我们已经尝试使用行边界,但还没有看到它如何在后台进行迭代。 我们希望在最小化内存使用和减少数据库访问次数之间取得平衡。 我们也对纯JDBC方法持开放态度,但我们希望该解决方案能够在不同的数据库上工作

我们试图迭代数据库中的大量行,并将它们转换为对象。行为如下:

结果将按序列id排序,当序列id更改时,将创建一个新对象。创建的对象将被发送到一个外部服务,有时在发送另一个服务之前必须等待,这意味着不会立即使用下一组数据 我们已经在iBATIS3中投入了代码,因此iBatis解决方案将是我们的最佳方法。我们已经尝试使用行边界,但还没有看到它如何在后台进行迭代。 我们希望在最小化内存使用和减少数据库访问次数之间取得平衡。 我们也对纯JDBC方法持开放态度,但我们希望该解决方案能够在不同的数据库上工作。 更新1:

我们需要尽可能少地调用DB 1调用将是理想的方案,同时还可以防止应用程序使用太多内存。对于这类问题还有其他解决方案吗?可能是纯JDBC或其他技术? 更新2

查询将由后端驱动,并且在给定的时间内只执行一个实例。
感谢并希望听到您对此的见解。

看来您需要某种分页。iBatis通过查询中的标准限制/偏移参数和iBATIS3中的RowBounds实现这一点

但是,如果我没有弄错的话,您似乎也在使用iBatis的GROUP BY功能,这样一个select返回N个记录,并带有N1 distint idx字段,就会创建N1个父对象,每个父对象都有几个子对象,总共创建了N个子对象。或者类似的

不幸的是,这两件事都是可以理解的

我在这里看不到任何灵丹妙药,人们可以想到许多方法,每种方法都有其缺点——没有更多的信息很难评估

如果主要对象是大量的记录,并且每个记录都将通过远程服务器单独处理,那么您甚至可能希望使用每页一个对象进行临时分页,在内部记住以前读取的id,比如选择。。。从…起其中id=从…中选择MINid。。。。其中id>lastid

我们需要尽可能少地调用DB 1调用将是理想的方案,同时还可以防止应用程序使用太多内存。对于这类问题还有其他解决方案吗?可能是纯JDBC或其他技术


您真的不应该担心数据库调用的数量。只需准确地查询最终用户需要立即查看的数据。做这件事再有效不过了。谷歌也不会查询整个数据库,只显示前10个。不,它会精确地查询这10个数据以进行显示,不会更少或更多。这比将整个数据库拖拽/复制到应用程序内存中并进行处理要快得多、效率更高。利用RDBMS的强大功能。这就是它的发明目的。

1。我感觉iBatis在使用限制/偏移量,我想这意味着它需要为每个页面访问数据库,对吗?2.我们在Java端进行分组,因此不需要在查询中使用group by关键字,我们只需要将结果按id排序,这样我们就可以在处理下一个对象之前完成创建一个具有相同id的子对象。3.您的临时分页听起来像是RowBounds方法的一个很好的替代方法。这样我们就可以保证只检索下一个对象。我会试试看性能。谢谢你的帮助leonbloy!我添加了一个新的要求,即尽可能减少DB往返。希望你也能对更新发表评论。谢谢如果您坚持在一个DB查询中执行此操作,请查看RowHandler或ResultHandler—或者更离奇的是,返回一个ResultSet/Cursor—或者恢复到普通JDBC。但是,只有在远程为每个对象执行的操作应该能够快速响应的情况下,这才是合理的-不依赖于某些人工交互,并且您可以相信循环将完成。我相信ResultSet/Cursor方法就是我的老板所寻找的。我刚刚看到了一个关于PostgreSQL设置FetchSize、仅使用ResultSet.TYPE_FORWARD_和setAutocommitfalse来启用此行为的教程。不幸的是,我现在正在用MySQL尝试这一点,但它看起来不受支持。你知道哪个星展银行有这个吗?谢谢。好的,我在MySQL的驱动程序URL中添加了?useCursorFetch=true,内存使用率从364651264下降到4160608。接下来,我将尝试检查DB2和Oracle是否支持setFetchSize。谢谢,谢谢,巴卢斯。抱歉,但我忘了提到这将不是一个用户驱动的查询,而是一个由后端触发的查询。我不知道为什么老板想要一个DB调用,我提到用这种方法平衡内存使用可能很困难,但他建议继续尝试,这就是为什么我不喜欢
我会寻找其他的选择。一般来说+1巴卢斯克是对的,我怀疑特别是also@paul如果老板这么说的话和他谈谈。说服他更多。